22 December 2016

Inject Javascript into Android WebView

Here's an interesting one I stumbled across the other day. The ability to "inject" some javascript into a webview and override the existing javascript for a webpage.

Let's say you want to override an existing javascript function, maybe one that's broken or you just want to change functionality. This is possible using onPageFinished.

Now I'm not going to say you *should* do this, nor will I say it is recommended or a good idea. I'm just pointing out that it's possible and saying it's mildly interesting.
Obviously there are warnings that go with enabling javscript on your webview and you should take heed of them over my example here.

Here's my HTML that I will load in a webview. For this example I've loaded it locally from my assets folder. I see no reason why this wouldn't work on a remote page.


<html>
    <head>
        <title>hello</title>
        <script>
            function myFunction() {
                document.getElementById("demo").innerHTML = "Gonzo was here";
            }
        </script>
    </head>
    <body>
        <p>
            <button name="Sumit" label="Submit" value="Submit" id="Submit" onclick="myFunction()">Submit</button>

            <br /><br />
            <div id="demo">Hello</div>
        </p>
    </body>
</html>


Let's try and change that javascript function to do something else:


final WebView webView = (WebView) findViewById(R.id.webView);

webView.setWebViewClient(new WebViewClient() {
    @Override
    public void onPageFinished(WebView view, String url) {
        super.onPageFinished(view, url);
        webView.loadUrl("javascript:function myFunction(){document.getElementById(\"demo\").innerHTML = \"Paragraph changed.\";}");
    }
});

WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webView.loadUrl("file:///android_asset/test.htm");


As you can see we've injected a custom function that overrides the results with a different output. Interesting huh?