onPageFinished in WebViewClient doesn't seem to fire correctly - android

I have seen one other SO question on this and it was not resolved.
I am using LoadData() with application generated html.
I noticed when I add a few blank lines after new text the page scrolls and the text takes a moment to magically appear (no scrolling, it just appears as in a fade-in.).
Watching .getContentHeight() it does not update in the onPageFinshed() event, but it is updated on subsequent additions of text on the page.
I created a timer event to watch getContentHeight. Even after I found getContentHeight had changed and issued a browser.pageDown(true) the page still did on scroll to the bottom.
It seems to be working fine when entering the activity for the first time. My problem only happens with I append a few lines to newInnerHTML.
Additionally the view involved has a header and footer with the browser in the middle. The webView is NOT behind the footer.
Is this a bug, or am I missing something?
TIA,
Jim
this code is within the onCreate for the activity.
final WebView browser = (WebView) findViewById(R.id.webview);
browser.setWebViewClient(new WebViewClient() {
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(browser, url);
// browser.computeScroll(); //didn't help
Log.d(TAG,"page getContentHeight: " + browser.getContentHeight());
Log.d(TAG,"page finished");
browser.pageDown(true);
}
});
This method is after the onCreate for the activity
private void UpdateMessageDisplay() {
//loadData fires onPageFinished but without the new data
browser.loadData("<html><body>" + newInnerHTML + "</body></html>", "text/html", "utf-8");
//reload() again fires onPageFinished but this time with new data
browser.reload();
}

I received a partial answer here, which does get the pageDown(true) to fire.
webview loaddata scroll setting not updating till clicked
There are still some issues.

Related

WebView tries to submit form when only one input is available on page

I need to load an HTML page with a form that has only one number input field. The desired behavior is:
When the user enters some data in this field and clicks on forward button from the Android's keyboard, a function is executed and a value appears, without taking him to another page.
The problem is that when the user clicks forward, the app crashes due to a FileUriExposedException. After searching a bit, I saw that this error is related to this bug.
One of the solutions shown in (2) was add an extra invisible form field, but does anyone know another solution? Because I think that changing all HTML forms will be something much more time consuming than trying a solution via Android.
Not sure if avoiding clicking forward would help, but here is a way you can submit to the form without the user typing in the form directly, if you have them enter the number into an edittext, save its value and then use something like this. You can set the webview visibility to invisible if you want to start and then make it visible after it submits. You can find out the IDs of the elements in the form by right clicking and hitting Inspect.
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.getSettings().setDomStorageEnabled(true);
mWebView.loadUrl(getString(R.string.form_url));
mWebView.setWebViewClient(new WebViewClient(){
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
String fieldID;
String submitButtonID;
int numberTypedInByUser
mWebView.loadUrl("javascript: {" +
"document.getElementById('"+fieldID+"').value = '"+numberTypedInByUser+"';" +
"var z = document.getElementById('"+submitButtonID+"').click(); };");
}
});

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);
}
});
}

WebView disappears when I click on an embedded link

I've done alot of Googling on this and haven't found an answer. I have a webview as part of an overall layout with other controls. I use the webview to show formatted text (recipe descriptions with bold and italic fonts) and URLs. The URLs point to Youtube and are fully qualified (ie. http://www.youtube.com/watch?v=fyzyhuVgzRE). When I click on the link in my web view, the web view control itself disappears from the layout (leaving the rest of the controls on the page intact) and the default web browser does not launch.
It behaves as if I've set the visibility of the web view to GONE, but I do not manipulate the visibility of any of the controls on the layout.
One interesting clue in the LogCat output is an INFO level message from the OS:
MotionRecognitionManager .unregisterListener : / listener count = 0->0,
listener=android.webkit.ZoomManager$1#41ac2fc0
Any ideas what would cause this behavior?
EDIT
Here is how I setup the webview in the onCreate() method of the activity:
webView1 = (WebView)findViewById(R.id.webView1);
webView1.getSettings().setJavaScriptEnabled(true);
webView1.getSettings().setAllowFileAccess(true);
webView1.setWebViewClient(new MyWebViewClient());
And the MyWebViewClient class:
private class MyWebViewClient extends WebViewClient {
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url != null && url.startsWith("http://")) {
view.getContext().startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
return true;
} else {
return false;
}
}
}
Oddly enough the shouldOverrideUrlLoading is never called.
Well, I'm a dope. It turns out that the double quotes in the href attribute of the anchor were doubled. My system integrates with a MySQL db over the web and I have to do alot of transformation of data between MySQL/PHP and Android/SQLite. During one of these transformations I double-escaped the quotes in the href. So what should have been:
Link Text
was instead rendered as:
Link Text
In the web view the resulting URL looked fine. It was underscored properly and looked like any other URL. It is odd though that simple doubling the quotes causes the behavior. I'll see if there is a known bug like this for Android. At the very least the WebView should through some kind of exception, not simply disappear from the screen.
I faced this type of behavior when webview tries to load content it cant handle. Intercept ref clicks using WebViewClient and send intent to open this ref in external application. Check this thread.

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);
}

WebView does not display loaded Html on some phones

I have a WebView in one of my Activities where I want to load a Html page. The page contains jquery-mobile and some html. So I do the following in my Activity :
mWebView=(WebView) findViewById(R.id.MyWebView);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.setWebViewClient(new WebViewClient(){
[...]
});
mWebView.loadUrl("http://www.mymobilepage.html");
The problem is that the page gets loaded and displayed on the emulator, and on a HTC Desire, but when I try to load it on a LG Optimus One nothing gets displayed. The events onPageStarted and onPageFinished both get fired in my WebViewClient but just a blank page is displayed, and also I don't have any errors in my LogCat.
Thanks in advance.
When onPageFinished is called, the page may not be completely rendered. The documentation states:
Notify the host application that a page has finished loading. This method is called only for main frame. 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, note that onNewPicture is documented as deprecated and obsolete. I ask about a replacement/alternative here.
This should be a comment, but since there is a bit of code on it I've added as response.
Try changing default background to transparent and alerting as soon as the page is loaded, just to be sure that at least the html is being interpreted:
mWebView = (WebView) this.findViewById(R.id.webview);
mWebView.setBackgroundColor(0);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.getSettings().setJavaScriptCanOpenWindowsAutomatically(false);
mWebView.setWebViewClient(new WebViewClient(){
#Override
public void onPageFinished(WebView view, String url)
{
super.onPageFinished(view, url);
view.loadUrl("javascript:(function() { alert('hello'); })()");
} });
and when loading the webpage:
mWebView.clearView();
mWebView.loadUrl("http://yourmobilepage.something/");
and let us know if something happened.
Try this:
webView.post(new Runnable() {
#Override
public void run() {
// Your code here...
}
});
Have you checked your html/js code with different versions on the emulator? Newer Android versions have newer versions of WebKit, that might be the problem.
I would also check if you have LogCat set to show Error messages only, or Debug+Info+Warning+Error messages. According to this, the javascript errors should show up as Debug messages.
I had a similar issue to this, I found that calling clearview and then reload seemed to clear it up -- as in:
mWebView.clearView();
mWebView.loadUrl("http://yourmobilepage.something/");
mWebView.reload();

Categories

Resources