I've been trying to inject some js into a webview in my app. Have been using
onReceivedTitle method of WebChromeClient since I want to execute the js while the page is loading.
This has been working until now. But recently, I observed that onReceivedTitle is not called we reload the webpage, similar to window.location.reload.
Firstly, I can't understand why it shouldn't be called. Or it should be and it's a bug?
Secondly, now that we know it's not called, where else can I inject by js?
Thanks.
Apparently, this is not considered an Android bug, but rather a Chrome or Chromium-based WebView bug. It should be reported to http://crbug.com/.
I'll suggest you to try a workaround with custom WebViewClient:
You'll have to use a custom WebViewClient to get this done. You will override the onPageFinished() method so when a new page finishes loading you can set the webview to the appropriate title.
Below is a sample implementation of the above:
WebView mWebView = (WebView) findViewById(R.id.mwebview);
mWebView.setWebViewClient(new WebViewClient() {
#Override
public void onPageFinished(WebView view, String url) {
ExperimentingActivity.this.setTitle(view.getTitle());
}
});
This answer here will prove to be useful:https://stackoverflow.com/a/8193479/9080948
Seems like this is a bug in chromium. I worked around this by injecting my scripts on onPageFinished method of WebviewClient.
Related
I'm writing an SDK for android which needs to injects JavaScript code into webviews it finds by enumerating the UI.
After finding a webview, the code sets a WebViewClient by using setWebViewClient() and waits for onPageFinished() to perform the actual injection.
All was working well, until I tried to use this method on a Cordova 8 application.
The WebView used by Cordova 8 is a subclass (org.apache.cordova.engine.SystemWebView) that overrides the setWebViewClient() method in the following way:
public void setWebViewClient(WebViewClient client) {
this.viewClient = (SystemWebViewClient)client;
super.setWebViewClient(client);
}
Because of the casting to SystemWebViewClient, I get a cast exception.
I want my solution to be as generic as possible, so extending SystemWebViewClient is not an option, but I still need to know when the webview page is loaded in order to inject the JavaScript.
Is there any way to get a notification when a webview has finished loading a page without using WebViewClient and webView.setWebViewClient() ?
A potential workaround would be to use WebChromeClient instead, and override its onProgressChanged method as follows:
WebView webView = new WebView(this);
webView.setWebChromeClient(new WebChromeClient() {
#Override
public void onProgressChanged(WebView view, int newProgress) {
if (newProgress == 100) {
// Do your injection here
}
}
});
It is possible to achieve this currently in Android? I only can find deprecated questions about old methods (CookieSynchManager) which not seems to work for this actually.
It is possible to achieve it? I can't find anything also on the Android Developers' Guide.
Having the same problem...I solved reading the doc here:
https://developer.android.com/reference/android/webkit/CookieSyncManager
For future readers: to force the Cookie sync process you can manually call the flush() method of CookieManager
I personally put in webview the following code:
public class MyWebViewClient extends WebViewClient {
public void onPageFinished(WebView view, String url) {
CookieManager.getInstance().setAcceptCookie(true);
CookieManager.getInstance().acceptCookie();
CookieManager.getInstance().flush();
}
}
Since CookieSynchManager is deprecated, CookieManager.getInstance() is the CookieManager instance for your entire application. Hence, you enable it by
CookieManager.getInstance().setAcceptCookie(true)
setAcceptCookie(boolean accept);
Sets whether the application's WebView instances should send and
accept cookies.
https://developer.android.com/reference/android/webkit/CookieManager.html
is it possible to show jquery or javascript popup message in android WebView ?
You can display popup message with the JavaScript alert(), confirm(), or prompt(). If they are not working then something else is wrong. Ensure your JavaScript is properly reaching those statements. Use console.log() to write messages to LogCat to trace your execution. Also make sure JavaScript is enabled. IE:
myWebView.getSettings().setJavaScriptEnabled(true);
You can simply use the line given below to show a alert in webview:
wv.loadUrl("javascript:alert('hello Android');");
If you want to make some changes in UI you can call javascript like given below in overridden function onPageFinished()
wv.setWebViewClient(new MyWebViewClient(){
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
wv.loadUrl("javascript:document.getElementById('client').style.visibility ='hidden';");
}
}
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();
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