Android WebView seems to behave different for each device - javascript

I'm building an app that is dependend on WebViews to render HTML-files in the assets folder. These files contain Javascript. The app works perfectly on my own device, including all the Javascript. But the Android emulator from Android Studio executes only some of the Javascript, on some of the pages. And the device from one of the testers shows blank pages instead of the HTML-files. And the device from another one of our testers also doesn't execute all the Javascript properly.
So, I'm not really sure what to do here. All pages are loaded with the exact same WebView-method and most of the Javascript is also similar. I can't debug or release an app that behaves differently on each device.
The code to load the WebViews:
WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.addJavascriptInterface(new WebAppInterface(this), "Android");
WebSettings webSettings = myWebView.getSettings();
CookieManager.getInstance().setAcceptCookie(true);
webSettings.setJavaScriptEnabled(true);
webSettings.setAllowFileAccessFromFileURLs(true);
webSettings.setAllowUniversalAccessFromFileURLs(true);
webSettings.setAllowFileAccess(true);
webSettings.setAllowContentAccess(true);
webSettings.setDomStorageEnabled(true);
webSettings.setLoadWithOverviewMode(true);
myWebView.setWebChromeClient(new WebChromeClient() {
public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
callback.invoke(origin, true, false);
}
});
myWebView.loadUrl("file:///android_asset/www/file.html");
myWebView.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
view.loadUrl(request.toString());
return true;
}
});
Once again, the app works perfectly on my own Android device. Even after I reinstalled it. I just don't see why it wouldn't work on other devices. Does someone have a solution or explaination?

I advice you to use the WebView Remote Debugging,so that you can see the source code that running in the WebView of your html fileļ¼Œand then you can click the web page in you Chrome Browser to see how the page react.
That is the way I took when I met some problem in webview.
all you need to do is just run the following code
if (Build.VERSION.SDK_INT >= 19){
WebView.setWebContentsDebuggingEnabled(true);
}
or you can find more detail about remote-debugging

Related

Android WebView WebArchive freeze after loading

I'm currently developping an android app for a tablet and I want to cover the use case : "if there is no internet connection, I want the app to run as normal".
I used a webview to load a survey in the app so once installed inside our stores, I won't have to install a new version each time we need a new makeover or add questions.
To cover the case where there is no connection, I save a webArchive that I load if there is no wifi when I need to load the webpage.
private void setMainView() {
mainview = (WebView) findViewById(R.id.wvMain);
WebSettings webSettings = mainview.getSettings();
webSettings.setLightTouchEnabled(true);
webSettings.setJavaScriptEnabled(true);
webSettings.setDomStorageEnabled(true);
webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
JavaScriptInterface myJavaScriptInterface = new JavaScriptInterface(this);
mainview.addJavascriptInterface(myJavaScriptInterface, "AndroidFunction");
if (DetectConnection.checkInternetConnection(this)){
mainview.setWebViewClient(new WebViewClient() {
public void onPageFinished(WebView view, String url) {
File webpage = new File(context.getExternalFilesDir(Environment.DIRECTORY_DCIM).getAbsolutePath()+ File.separator +"home.mht");
mainview.saveWebArchive(webpage.toString());
editor.putString(BuildConfig.HOME_PAGE_WEB_ARCHIVE_FILE,webpage.toString() );
editor.commit();
}
});
mainview.loadUrl(BuildConfig.SERVER_URL + BuildConfig.HOME_PAGE);
}
else{
String filename = getSharedPreferences(BuildConfig.PREFERENCES_NAME, 0).getString(BuildConfig.HOME_PAGE_WEB_ARCHIVE_FILE,null);
mainview.setWebChromeClient(new WebChromeClient());
mainview.loadUrl("file:///"+filename);
}
}
The only problem is that the webarchive froze as soon as it is loaded. I tried many thing to make it works but the solution is escaping me.
When I set my application to plane mode and I reload the app, I see the home page fine but the click events don't work. My Android Javascript interface is also not working as I tested to send Toast to debug when the app is finished loading so I'm guessing the javascript is not working in my webarchive or maybe the webarchive is not including the CSS and Javascript that are from other website such as W3.css and JQuery?
Maybe if I used a local version of these asset they will be included in the webarchive.
Any suggestions would be welcome.
Thanks
I ended up using the cache of my webview instead of loading a web archive.
I first added a cache.appcache a the root of my webpage linking my main page to it.
<html manifest="cache.appcache">
At the root (wwww/http_doc) I added this file :
CACHE MANIFEST
/home
/thank-you
/css/w3.css
/js/jquery-3.3.1.min.js
/images/happy1.png
/images/happy2.png
/favicon.ico
#NETWORK
NETWORK:
/home
/thank-you
#FALLBACK
FALLBACK:
/home /offline.html
/thank-you /offline_thankyou.html
The fallback section allowed to have a html file to fall to if the network is available. I then activated the cache of my webview :
WebSettings webSettings = mainview.getSettings();
webSettings.setAppCacheEnabled(true);
webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);
webSettings.setAppCachePath(
getApplicationContext().getCacheDir().getAbsolutePath());
And now each time, I modified the file "cache.appcache" and reload the application, it take a copy of the current "offline.html" files and reload a working site according to the cache. A good thing I had a very static website to load from so it's 100% functionnal without an internet connection.

Android Webview Javascript won't work

I have list of tweets being displayed in my listview. I have setup a listener on my listview which should take the user to the specific tweet.
The listener on my list is as follow:
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Intent intent = new Intent(TweetActivity.this, WebActivity.class);
intent.putExtra("url", String.valueOf(twitterBaseURL+tweetResult.get(i).getId()));
startActivity(intent);
}
});
Inside my web activity class, I am doing something as follow:
String url = getIntent().getExtras().getString("url");
WebView webView = (WebView) findViewById(R.id.webView);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
webView.setWebChromeClient(new WebChromeClient());
webView.setWebViewClient(new WebViewClient());
webView.getSettings().setDomStorageEnabled(true);
webView.loadUrl(url);
In the web view it does not load the page like it does in google chrome on a mobile. I think the javascript does not load properly.
UPDATE 1:
I was testing this on an android device with API 21. Inside my android studio I have a virtual device with an API 23. In API 23 this loads everything properly. I created another virtual device with API 21 and tested to double check so the problem is with the API levels. This code works in API 23 to load the url properly inside the web view but does not in API 21?
Enabling JavaScript
JavaScript is disabled in a WebView by default. You can enable it through the WebSettings attached to your WebView. You can retrieve WebSettings with getSettings(), then enable JavaScript with setJavaScriptEnabled().
For example:
WebView myWebView = (WebView) findViewById(R.id.webview);
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
myWebView.loadUrl("file:///android_assets/your_page.html");
Take a look at this, although the issue talking about is react-native.
The last point mentioned there is about try running on a real Android device. And indeed sometimes Android emulator does not work as expected.
So I suggest testing your code on the real android device with API 21 first

Webview javascript not executing if there is some error in the html page

I am using webview in my app for payment. Now I have come across a scenario in which there is some error in the html content due to which a javascript in that page is unable to execute. While the same javascript is executing in desktop browser. What can be the issue? I have enabled javascript in my webview but still such a thing is happening
I have normal code for webview settings.
webView.setWebViewClient(webViewClient);
WebSettings webSettings = webView.getSettings();
webSettings.setDefaultZoom(WebSettings.ZoomDensity.FAR);
webSettings.setBuiltInZoomControls(true);
webSettings.setDomStorageEnabled(true);
webSettings.setSupportZoom(true);
webSettings.setJavaScriptEnabled(true);
webSettings.setSupportMultipleWindows(true);
webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
webSettings.setLoadWithOverviewMode(true);
webView.setWebChromeClient(new WebChromeClient());
webSettings.setPluginState(WebSettings.PluginState.ON);
webSettings.setAllowFileAccess(true);
Neither I can open that url due to lack of parameters

window.close() not working in android webview?

Android 4.1
Eclipse
Testing on device
I am trying to open a html/javascript webpage, hosted on my localhost for now, in my android application through a webview.
The page is suppose to just close after 2 sec through the below code
<script type="text/javascript">
alert('hello');
setInterval(function(){window.close();},2000);
</script>
I am able to get the hello alert by using WebChromeClient. But the window.close is still not working. Any help would be appreciated.
PS: Here is how i am loading the URL:
WebSettings ws = webView.getSettings();
ws.setJavaScriptEnabled(true);
ws.setJavaScriptCanOpenWindowsAutomatically(true);
webView.loadUrl("http://192.168.1.137/abc.html");
webView.setWebChromeClient(new WebChromeClient());
Try this :
WebChromeClient webClient = new WebChromeClient(){
public void onCloseWindow(Window w){
super.onCloseWindow(w);
Log.d(TAG, "Window close");
}
};
Description :
public void onCloseWindow (WebView window)
Notify the host application to close the given WebView and remove it from the view system if necessary. At this point, WebCore has stopped any loading in this window and has removed any cross-scripting ability in javascript.
It's not possible on android version > KITKAT. But I have find solution. If android build version > KITKAT, I have detected message from js on server side in method onConsoleMessage of WebChromeClient class http://developer.android.com/reference/android/webkit/WebChromeClient.html.
It works for me.

How to set Javascript properties in Android webview

I am building an Android application that loads a web application in to a web view. When a user visits the web application in a browser a pop up asking if they want to bookmark the page appears.
For the native app I want remove this.
For iPhone I was able to do this:
[webView stringByEvaluatingJavaScriptFromString:#"AppConfig.showBookmarkPrompt=false;"];
For Android I tried this:
#Override
public void onPageFinished(WebView view, String url) {
view.loadUrl("javascript:(function(){"+
"AppConfig.showBookmarkPrompt=false;})()");
}
The Android version doesn't work. I presume that the javascript is being run after the bookmark popup has been shown. I don't really know why the iPhone version does works and not the Android.
There are many other ways I can achieve my goals but I am wondering if anybody can explain why the iPhone method works and if there is something similar in Android. I have been reading about it through Google searches but it is still not entirely clear to me.
Thanks for any help I get.
EDIT
The problem was for Android I was passing a function in JavaScript where I should have just set the property like this: view.loadUrl("javascript:AppConfig.showBookmarkPrompt=false;");
There must be some difference in the way it is executed that I don't quite understand.
put this on onCreate() of Activity..
WebView myWebView = (WebView) findViewById(R.id.webview);
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
then call your code...
#Override
public void onPageFinished(WebView view, String url) {
view.loadUrl("javascript:AppConfig.showBookmarkPrompt=false");
}
For more info look at here.

Categories