screenshot from webview - android

I'm trying to take a screenshot of content of my WebView. I creare a bitmap and then create canvas from this bitmap, then I call method drawPage(canvas) inside onPageFinished() (that is a callback from WebChromeClient), but inside onPageFinished() webView still hasn't loaded content, so I see just black page at first, and then I see previous pages(because when I call it second time previous pages are loaded to webView). How could I deal with this problem? I can solve it using hadlers with some delay, but I think there should be better way to do this.
Thanks for help.

I don't think I understand the problem, but are you asking how to trigger an event on a WebView loading a page? Could you create a WebView client and override the onPageCompleted()?
private WebViewClient viewClient {
#Override
public boolean onPageFinished(WebView view, String url) {
//here you can run your Bitmap creating code
return true;
}
}
YourWebView.setWebViewClient(viewClient);
Is this what your looking for?

Related

Android: Problems to display WebView for every url from the list

I have a standard task to display a ListView (UrlListView) with urls. When the user touches the row I open an activity (UrlViewActivity) with WebView.
Unfortunately, this trivial task brings many troubles for me in Android...
Standard approach:
UrlViewActivity has an *.xml file with a layout that contains WebView.
When the user touches any row inside UrlListView, I start this activity, set this layout as a content view, find my WebView by id and ask it to load an url. Yes, I also call inside my activity's onPause - mWebView.onPause() and inside onDestroy - mWebView.destroy();
Everything works pretty good until the user tries to open various urls rather often: opens an url, closes UrlViewActivity, opens another url and e t. c...usually after 15-25 such loads (every UrlViewActivity launch creates a new WebView) famous Android 4.4 bug occurs on Moto X and Nexus 5:
https://code.google.com/p/android/issues/detail?id=73632
so my app freezes inside nativeLockCanvas...
Then I tried another approach that some guys on StackOverFlow recommended:
Keeping WebView as a static object, create it only during the first startup and on every UrlViewActivity launch add this WebView and clear its state (and remove this WebView inside onStop() of course).
No freezing!!!
But there is a big problem to clear WebView's state on Android:
It's really hard to force a WebView correctly measure its height when loading a new url (WebView always tries to remember previous long page and doesn't want to decrease it height even when loading a very small page).
There are many advices to reset WebView's height like the following: How a change the content size of a webview in android?
But unfortunately clearView() is already deprecated and does nothing...The only working approach that I found is: calling mWebView.loadUrl("about:blank"); and inside overriden onPageFinished(WebView view, String url) method call mWebView.requestLayout();
That really works and pages become finally take correct height and scrolling works ok, but...it remembers blank page inside its history and shows it to user when he presses back button...
To resolve the problem of storing blank page in WebView's history I've tried to use clearHistory() method, but...if I call this method inside onPageFinished(WebView view, String url) right after my correct page was loaded guess what? WebView mystically forgets that it has just measured itself correctly (during first onPageFinished(WebView view, String url) call when "about:blank" page was loaded) and shows long scrolling even for a short pages...
Here is my code snippet:
enum WebViewStates {
WEB_VIEW_INITIALIZED, WEB_VIEW_RESET_DONE, WEB_VIEW_HISTORY_CLEARED
}
private ViewGroup mWebViewContainer;
private WebViewStates mWebViewState;
private void setupWebView() {
mScrollView.smoothScrollTo(0, 0);
mWebViewContainer.addView(mWebView);
mWebViewState = WebViewStates.WEB_VIEW_INITIALIZED;
mWebView.loadUrl("about:blank");
mWebView.setWebViewClient(new WebViewClient() {
#Override
public void onPageFinished(WebView view, String url) {
switch (mWebViewState) {
case WEB_VIEW_INITIALIZED:
mWebViewState = WebViewStates.WEB_VIEW_RESET_DONE;
mWebView.requestLayout();
mWebView.loadUrl(mPreviewUrl);
break;
case WEB_VIEW_RESET_DONE:
mWebViewState = WebViewStates.WEB_VIEW_HISTORY_CLEARED;
mWebView.clearHistory();
break;
case WEB_VIEW_HISTORY_CLEARED:
break;
}
super.onPageFinished(view, url);
}
});
}

Can you measure the time it takes to load a web page in a webView in Android?

There are lots of questions regarding the WebView in Android taking too long to load, however I'd like to be able to time exactly how long it takes to completely load, and then display the result.
Is this possible? I could start a timer but does the WebView have an HTML OnLoad style call once it has loaded?
The code I have is basic:
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
setContentView(R.layout.pageloadtest);
webView = (WebView) findViewById(R.id.webView1);
webView.loadUrl("http://www.airometricwireless.com");
}
This loads the page fine. I just need to time how long it takes.
Probably not scientifically accurately, but I guess you could call
long a, b;
mWebView.setWebViewClient(new WebViewClient() {
public void onPageStarted(WebView view, String url) {
a = (new Date()).getTime;
}
public void onPageFinished(WebView view, String url) {
b = (new Date()).getTime;
}
});
Then b - a.
Hope it helps.
Best regards.
You can use onPageFinished but as the docs say, "When onPageFinished() is called, the rendering picture may not be updated yet."
Also it's only meaningful for simple pages as it won't factor in IFRAMEs or dynamically-loaded content e.g. JavaScript that loads other JavaScript such as social media buttons, adverts, tracking scripts etc. And it's typically that stuff that causes pages to feel unperformant.
What people often mean when they say "it's slow to load" is "it takes a long time before I can interact with the page" which is very different from how long it takes to load the assets. For this you probably want to test when an onDOMReady-like event fires from JavaScript, or if not using that, when non-deferred JS actually initialises.
Essentially, as soon as you have any dynamic loading behaviours in the page, onPageFinished becomes meaningless, and you need to measure with JS.
As with any performance problem;
measure the interaction to discover the bottlenecks
try to fix a bottleneck & measure again
repeat until performance is acceptable.
To get page loading finish, use
webView.setWebViewClient(new WebViewClient() {
public void onPageFinished(WebView view, String url) {
// do your stuff here
}
});

How to setVisibility(View.VISIBLE) to a webView AFTER its loaded its contents?

In my app there is an advertising web view, that is calling an url when the activity starts.
Everything is nice except one minor thing, it is more like a visibility issue...
So the thing is when i start the activity i literally see the page loading.. About in 0,3 seconds the texts appear then the pictures, and all the content somehow floating in from left to right. It not so nice, i would like to set the visibility of my webView to VIEW.GONE until it is done with the loading, and after that i could set it VISIBLE...
Is there a good, and working way for achieve this?
It is important that it is must work on Android 2.3 to 4.0 in each and every OS version.
I already tried onPageFinished and PictureListener related to this stack question here, but no hope, onPageFinished only works properly on 4.0 and PictureListener is for pictures which is not the best way to do this in case of different advertisings with different number of pictures. (and what if there is no picture at all...)
Please if you know a way let know with me. Thanks all.
have you tried WebChromeClient ?
webView.setWebChromeClient(new WebChromeClient() {
public void onProgressChanged(WebView view, int progress) {
if (progress == 100) {
// dismisses the PD
dismissLoadingDialog();
}
}
});
webView.loadUrl("your-Url");
// show message dialog here
createLoadingDialog();
i have used this on 2.3 to 4.0 OSes without any issue
Use webview visibility during onPageFinished method
view not display util all page loading.
webView1.setWebViewClient(new WebViewClient(){
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
webView1.setVisibility(View.VISIBLE);
}

How to know when WebView rendering is finished

I want to display a progress bar while the WebView is loading. I am hiding it on OnPageFinished(), but this is too early. The Webview is still rendering the image.
The WebView documentation states: "When onPageFinished() is called, the rendering picture may not be updated yet. To get the notification for the new Picture, use onNewPicture(WebView, Picture)."
However, OnNewPicture and the PictureListener interface is deprecated and obsolete. Is there another way to know that the rendering is complete?
Unfortunately, I have found that there is no event or mechanism to truly know when the page is completely loaded and finished rendering.
How about creating a custom WebChromeClient and overriding its onReceivedIcon() or onProgressChanged() methods. The onReceivedIcon() will be triggered once the favIcon is loaded and and using the onProgressChanged(), you can enquire the progress of the webview loading. I hope this helps
Please refer to this code snippet
webView.setWebChromeClient(new CustomWebChromeClient());
You can use onProgressChanged or onReceivedIcon whatever that suits your needs.
public class CustomWebChromeClient extends WebChromeClient {
#Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
if (newProgress==100) {
progressBar.setVisibility(View.GONE);
progressBar.setProgress(newProgress);
}
}
#Override
public void onReceivedIcon(WebView view, Bitmap icon) {
// icon received here
super.onReceivedIcon(view, icon);
}
}
I think you can add and execute JavaScript function at the end of body tag of your web page to call your JavaScript interface function to hide the progress bar. But, beware of enabling JavaScript on your WebView.
I'm suffering same problem, but there is no way to know the timing.
The only way I use is to give enough room for the rendering completion by postDelayed().
In my case 200ms is enough if u don't use heavy contents more than 200K in text.

Hide the URL bar in Android Webkit

This doesn't seem to work in jqTouch or iUI. But I know it's possible because it works on my Droid when I go to deviantart.com . Anyone know how to do it?
Thanks!
Ok, I'm gonna answer my own question here. I added this bit of jQuery...
$(document).ready(function() { setTimeout(scrollTo,200,0,1) });
The timeout appears to be necessary. On my Droid, the document is not yet ready to scroll when the DOMContentLoaded event is fired.
Have you tried firing the function on window.load and on pageAnimation events?
// Hide URL bar when loading the first page
$(window).load( function() {
setTimeout(scrollTo,200,0,1);
});
// ...and on every subsequent request handled by jQTouch
$(document).delegate("body", "pageAnimationStart pageAnimationEnd", function() {
setTimeout(scrollTo,200,0,1);
});
if you are using a webkit i'm assuming that you have created an on create method, create a class below it that looks something like this
private class CallBack extends WebViewClient
{
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url)
{
browser.loadUrl(url);
return true;
}
}
declare a webviewclient, and a webview when creating the parent class
WebView browser;
WebViewClient browserClient;
that should keep your app from opening an external browser.
Went through the same problem when i was starting my app project, so I hope this helps

Categories

Resources