Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Web-View : Inject local Javascript file to Remote Webpage

It has been asked many times before, I browsed through everything, no clear answers yet.

Question simplified: Is it possible to inject local Javascript file (from asset or storage) to remote webpage loaded in an Android Web-View? I know that it is possible to inject such files to local Webpages (Assets HTML) loaded in a Web-View.

Why do I need this to work? : To make browsing experience faster, by avoiding downloading of bigger files such as Js and CSS files every time. I want to avoid Web-View Caching.

like image 586
sumit Avatar asked Feb 04 '14 12:02

sumit


People also ask

What is the use of WebView in android?

The WebView class is an extension of Android's View class that allows you to display web pages as a part of your activity layout. It does not include any features of a fully developed web browser, such as navigation controls or an address bar. All that WebView does, by default, is show a web page.

How do I enable JavaScript on Android WebView?

This example demonstrate about How to enable webview java script in android. Step 1 − Create a new project in Android Studio, go to File ⇒ New Project and fill all required details to create a new project. Step 2 − Add the following code to res/layout/activity_main. xml.


1 Answers

There is a way to 'force' the injection of your local Javascript files from local assets (e.g., assets/js/script.js), and to circumvent the 'Not allowed to load local resource : file:///android_assets/js/script.js ...' issue.

It is similar to what described in another thread (Android webview, loading javascript file in assets folder), with additional BASE64 encoding/decoding for representing your Javascript file as a printable string.

I am using an Android 4.4.2, API level 19 Virtual Device.

Here are some code snippets:

[assets/js/script.js]:

    'use strict';      function test() {        // ... do something     }      // more Javascript 

[MainActivity.java]:

    ...      WebView myWebView = (WebView) findViewById(R.id.webView);     WebSettings webSettings = myWebView.getSettings();      webSettings.setJavaScriptEnabled(true);     webSettings.setAllowUniversalAccessFromFileURLs(true);     myWebView.setWebViewClient(new WebViewClient() {        @Override        public boolean shouldOverrideUrlLoading(WebView view, String url) {           return false;        }         @Override        public void onPageFinished(WebView view, String url) {           super.onPageFinished(view, url);            injectScriptFile(view, "js/script.js"); // see below ...            // test if the script was loaded           view.loadUrl("javascript:setTimeout(test(), 500)");        }         private void injectScriptFile(WebView view, String scriptFile) {           InputStream input;           try {              input = getAssets().open(scriptFile);              byte[] buffer = new byte[input.available()];              input.read(buffer);              input.close();               // String-ify the script byte-array using BASE64 encoding !!!              String encoded = Base64.encodeToString(buffer, Base64.NO_WRAP);              view.loadUrl("javascript:(function() {" +                           "var parent = document.getElementsByTagName('head').item(0);" +                           "var script = document.createElement('script');" +                           "script.type = 'text/javascript';" +              // Tell the browser to BASE64-decode the string into your script !!!                           "script.innerHTML = window.atob('" + encoded + "');" +                           "parent.appendChild(script)" +                           "})()");           } catch (IOException e) {              // TODO Auto-generated catch block              e.printStackTrace();           }        }     });      myWebView.loadUrl("http://www.example.com");      ... 
like image 136
Raffaele N. Avatar answered Oct 09 '22 20:10

Raffaele N.