103

I'm trying to make an Android version of a relativly simple iOS app that uses a webview, some buttons and then relies on javascript calls to a CMS.

But I'm stuck at a pretty early point of development: The webview doesn't function with javascript.I've read a lot of posts about how to enable JS in an Android webview, but no luck so far.

Below is some of my code:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    mWebView = (WebView) findViewById(R.id.webview);
    mWebView.getSettings().setJavaScriptEnabled(true);
    mWebView.setWebChromeClient(new WebChromeClient());
    mWebView.setWebViewClient(new HelloWebViewClient()
    {
        @Override  
        public void onPageFinished(WebView view, String url)  
        {  
            //Calling an init method that tells the website, we're ready 
            mWebView.loadUrl("javascript:m2Init()");
            page1(mWebView);
        }  
    });
  mWebView.loadUrl("http://my_url/mobile/iphone//app.php");  
}

private class HelloWebViewClient extends WebViewClient {
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        view.loadUrl(url);
        return true;
    }

}


@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) {
        mWebView.goBack();
        return true;
    }
    return super.onKeyDown(keyCode, event);
}

public void page11(View view)
{
    mWebView.loadUrl("javascript:m2LoadPage(1)");
}

What am I doing wrong here? The URL is working perfectly in my iOS app, and in a browser. But not in my app!

Please tell me it's something obvious...

David K
  • 3,153
  • 5
  • 18
  • 27
  • 35
    Uhm, why is someone voting my question down? I've spend a lot of time researching but havent found anything, so I'd say my question is very valid :/ – David K Sep 25 '11 at 20:29
  • 1
    i found a post that answer this questions [android webview geolocation][1] [1]: http://stackoverflow.com/questions/5329662/android-webview-geolocation?answertab=votes#tab-top – yanddam Aug 30 '12 at 16:29
  • Beginners can also see http://tutorials.jenkov.com/android/android-web-apps-using-android-webview.html, there are many tips about WebView. – CoolMind Aug 26 '20 at 14:42

12 Answers12

157

FIXED! Spurred on by the error, I found out that I needed to set

setDomStorageEnabled(true)

for the webview settings.

Thanks for your help Stephan :)

Rumit Patel
  • 8,830
  • 18
  • 51
  • 70
David K
  • 3,153
  • 5
  • 18
  • 27
62

In case something with WebView on Android does not work, I always try to make sure I set these crazy flags such as,

    WebSettings webSettings = webView.getSettings();
    webSettings.setJavaScriptEnabled(true);
    webSettings.setDomStorageEnabled(true);
    webSettings.setLoadWithOverviewMode(true);
    webSettings.setUseWideViewPort(true);
    webSettings.setBuiltInZoomControls(true);
    webSettings.setDisplayZoomControls(false);
    webSettings.setSupportZoom(true);
    webSettings.setDefaultTextEncodingName("utf-8");

I wonder why these are not set by Default, who would expect webpages without javascript content nowadays, and whats the use having javascript enabled when DOM is unavailable unless specified. Hope someone filed this as a bug or improvement/feature-request already and the monkeys are working on it.

and then there is deprecated stuff rotting somewhere, like this:

webView.getSettings().setPluginState(PluginState.ON);

All this for loading webpages inside app.

On iOS, its all so simple - Swift 3.0

private func openURLWithInAppBrowser(urlString:String) {
    guard let url = URL(string:urlString) else {
        return
    }
    let sfSafari = SFSafariViewController(url:url)
    present(sfSafari, animated: true, completion: nil)
}
computingfreak
  • 4,939
  • 1
  • 34
  • 51
12

Mainly, these three lines will be enough to make the Javascipt work in webView...

webSetting.setJavaScriptEnabled(true);
webView.setWebChromeClient(new WebChromeClient());
webView.setWebViewClient(new WebViewClient());

If it's not working after that also, then add below line also.

webSettings.setDomStorageEnabled(true);

Actually, you need both setJavaScriptEnabled() and setWebChromeClient(new WebChromeClient()) to make the JavaScript work. If you will use only webSetting.setJavaScriptEnabled(true); then it won't work.

Mrudul Tora
  • 715
  • 8
  • 14
9

Loading javascript in webview

webView.getSettings().setDomStorageEnabled(true);
Shivam Kumar
  • 1,892
  • 2
  • 21
  • 33
7

Add the following lines of code in your MainActivity.java

It helped me to enable js

  webSetting.setJavaScriptEnabled(true);
  webView.setWebChromeClient(new WebChromeClient());
  webView.setWebViewClient(new WebViewClient());

do not forget about this permission in AndroidManifest file.

<uses-permission Android:name="Android.permission.INTERNET" />
Riddhi Shah
  • 3,092
  • 5
  • 36
  • 56
prashant kute
  • 333
  • 4
  • 9
6

Did you enable the right internet permission in the manifest? Everything looks fine otherwise. By any chance, have you also tested this code on an actual Android phone? And not just on the emulator?

Here is a good tutorial on a slightly different approach. You may want to try that one to see if it works for you.

Stephan Branczyk
  • 9,363
  • 2
  • 33
  • 49
  • 1
    I've just tried it on my Samsung Galaxy SII, with no luck. Permission is added in the manifest as: I'll give the link a look :) – David K Sep 26 '11 at 08:35
  • I've downloaded the sample of the project you linked, which works, but adding my URL is still a no go. The strange thing is, that if I just type the url in androids own browser (not through the webview in my app), it works. So strange.. – David K Sep 26 '11 at 08:47
  • What happens when you use the ip address number instead of the domain name? Also, can you try it again with the domain name, but instead this time with a plain index.html page instead? I'm running out of ideas. Can you share with us the exact url you're using? If not, that's ok. I just thought I'd ask. My next step would be to try checking the http headers response codes your web app is returning. In some ways, I'm not surprised that the stock browser works, and your url loading doesn't. Internet browsers can be incredibly forgiving. Also, it could just be a user agent thing. – Stephan Branczyk Sep 26 '11 at 17:34
  • I've updated the code with the original URL. The content is in danish, but that should'nt matter. I'll try checking http codes, but havent got access to the ip as the site isn't hosted by me, but a friend, so that'll have to wait. – David K Sep 26 '11 at 20:46
  • Statuscode is 200, so thats not the problem. But I spotted an error in logcat: ERROR/Web Console(661): TypeError: Result of expression 'localStorage' [null] is not an object. at http://slagterfriis.moski2.net/mobile/iphone/assets/script.js:16 Any idea what this means? – David K Sep 26 '11 at 21:38
2

This video (http://youtu.be/uVqp1zcMfbE) gave me the hint to make it work. The key is to save your html and js files in the Android assets/ folder. Then you can easily access them via:

webView.loadUrl("file:///android_asset/your_page.html");
Nikos Hidalgo
  • 3,666
  • 9
  • 25
  • 39
user574199
  • 55
  • 7
2

If you are in Kotlin you can use the following method to get the JavaScript working :

webView.apply {
     loadUrl(
         "file:///android_asset/frm/my_html_landing_page_here.html"
     )

     settings.javaScriptEnabled = true
     settings.domStorageEnabled = true
 }

Also make sure that your entire folder is inside the Assets folder (this includes HTML, Javascript and other file needed)

Nikos Hidalgo
  • 3,666
  • 9
  • 25
  • 39
ralphgabb
  • 10,298
  • 3
  • 47
  • 56
2

Xamarin Android also has the same problem that WebView does not execute any Javascript. Follow @computingfreak answer:

        this.SetContentView(Resource.Layout.activity_main);

        var webView = this.FindViewById<WebView>(Resource.Id.webView);

        var webSettings = webView.Settings;
        webSettings.JavaScriptEnabled = true;
        webSettings.DomStorageEnabled = true;
        webSettings.LoadWithOverviewMode = true;
        webSettings.UseWideViewPort = true;
        webSettings.BuiltInZoomControls = true;
        webSettings.DisplayZoomControls = false;
        webSettings.SetSupportZoom(true);
        webSettings.DefaultTextEncodingName = "utf-8";

Weirdly enough they changed all setter methods to properties except SetSupportZoom and SupportZoom stays as getter :/

Luke Vo
  • 17,859
  • 21
  • 105
  • 181
1

Just permit your WebView to run JS, simple like that:

WebView web=(WebView)findViewById(R.id.web);
web.getSettings().setJavaScriptEnabled(true);
PYK
  • 3,674
  • 29
  • 17
0

To enable javascript popups in WebView its necessary to set webChromeClient and override openFileChooser methods.

    mWebview.setWebChromeClient(new WebChromeClient(){
        // For Android 4.1+
        @SuppressWarnings("unused")
        public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
            mUploadMessage = uploadMsg;

            Intent i = new Intent(Intent.ACTION_GET_CONTENT);

            i.addCategory(Intent.CATEGORY_OPENABLE);
            i.setType(acceptType);

            startActivityForResult(Intent.createChooser(i, "SELECT"), 100);
        }

        // For Android 5.0+
        @SuppressLint("NewApi")
        public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
            if (mUploadMessageArr != null) {
                mUploadMessageArr.onReceiveValue(null);
                mUploadMessageArr = null;
            }

            mUploadMessageArr = filePathCallback;

            Intent intent = fileChooserParams.createIntent();

            try {
                startActivityForResult(intent, 101);
            } catch (ActivityNotFoundException e) {
                mUploadMessageArr = null;

                Toast.makeText(activity,"Some error occurred.", Toast.LENGTH_LONG).show();

                return false;
            }

            return true;
        }
    });

And handle the onActivityResult as below:

@SuppressLint("NewApi")
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == 100) {
        if (mUploadMessage == null) return;
        Uri result = data == null || resultCode != Activity.RESULT_OK ? null : data.getData();
        mUploadMessage.onReceiveValue(result);
        mUploadMessage = null;
    }

    else if (requestCode == 101) {
        if (mUploadMessageArr == null) return;
        mUploadMessageArr.onReceiveValue(WebChromeClient.FileChooserParams.parseResult(resultCode, data));
        mUploadMessageArr = null;
    }

}
0

If nothing above helped try to add delay in WebViewClient.onPageFinished listener

override fun onPageFinished(view: WebView?, url: String?) {
            Handler().postDelayed({
                //update your view with js here
                super.onPageFinished(view, url)
            }, 1000)
        }
Bohdan
  • 26
  • 1
  • 4