[Note that since I answered this, onNewPicture has been deprecated (see http://developer.android.com/reference/android/webkit/WebView.PictureListener.html and What does "This method is deprecated" mean for application developers). Unfortunately, there is no information on what replaces it, or at what API levels it was supported. I guess that means that you use this at your own risk.]
I think you’re correct that onNewPicture is the right place to capture a screenshot of a loaded WeView page, but also correct that it is hard to know when to actually do the capture.
It appears that WebView calls onNewPicture whenever there has been any drawing. For example, it calls onNewPicture repeatedly when the search bar is in keyboard entry mode and the cursor is flicking. Similarly, for some web pages (eg www.yelp.com/nyc) it calls onNewPicture repeatedly, even after the page has finished drawing, probably because of the flashing cursor in the Search box. But at the other extreme it will call onNewPicture only once (eg if the user drops down an iGoogle item).
So there’s no easy rule? The approach we’ve taken is to
- monitor a range of events that are involved / affect page loading – such as shouldOverrideUrl, onPageFinished, focus changes, scrolling start/end, in addition to onNewPicture
- run a timer (2secs is working well) on onNewPicture, reset by a new onNewPicture
- implement a page loading FSM which uses the events and timer expiry as inputs, and moves through a series of state/action transitions, to the point where it decides it genuinely has a new picture.
Not pretty, but it works, with very few cases where it captures the same picture twice – and no cases where it fails to capture a picture where it should.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…