Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Loading jQuery from local assets in Android for a remote html page

I'm trying to read a local javascript file (jQuery) stored in assets from an Android webview. I do not want to load-with-base-url since my images and html are served remotely.

To Summarize : - Load local jQuery (in assets folder) into a remotely loaded page in Android webview.

After long hours of browsing going in vain, I decided to put up this question here. Please help.

Thanks!

like image 910
Vijay Avatar asked Jul 08 '14 13:07

Vijay


2 Answers

  1. Define a Javascript Interface like the one below that will read your jquery file from assets directory

    class JavaScriptInterface {
    
        @JavascriptInterface
        public String getFileContents(){
            return readAssetsContent("jquery.js");
        }
    }
    
  2. Update WebView to enable JavaScript and to add JavaScriptInterface defined previously...

    webView.getSettings().setJavaScriptEnabled(true);       
    webView.addJavascriptInterface(new JavaScriptInterface(), "android");
    
  3. Add javascript code snippet in your remote HTML to read the jquery file content through android JavaScript Interface...

    <script type="text/javascript">
    var s = document.createElement('script');
    s.innerHTML = window.android.getFileContents();
    document.head.appendChild(s);
    
    //check if jquery is loaded now...
    if(typeof $ != "undefined") {
        $(document).ready(function() {
            $('body').css('background','green');
        });
    } else {
        document.body.innerText = "jQuery NOT loaded";
    }
    </script>
    
like image 135
Sachin Kumar Avatar answered Jan 21 '23 23:01

Sachin Kumar


First, in your Activity, create the static variable appContext, which holds the Application Context and function below:

 //Initialize Application Context
 private static Context appContext;

 //Get Application Context (for use in external functions)
    public static Context getContext() {
        return appContext;
    }

...and set the variable in onCreate(Bundle savedInstanceState):

     //Set application context (for use in external functions)
     appContext = this;

Second, create class in separate file below:

File: JavaScriptInterface.java

import android.content.Context;
import android.util.Log;
import android.webkit.JavascriptInterface;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;    

class JavaScriptInterface {        

    @JavascriptInterface
    public String getFileContents(String assetName){
        return readAssetsContent(MainActivity.getContext(), assetName);
    }

    //Read resources from "assets" folder in string
    public String readAssetsContent(Context context, String name) {
        BufferedReader in = null;
        try {
            StringBuilder buf = new StringBuilder();
            InputStream is = context.getAssets().open(name);
            in = new BufferedReader(new InputStreamReader(is));

            String str;
            boolean isFirst = true;
            while ( (str = in.readLine()) != null ) {
                if (isFirst)
                    isFirst = false;
                else
                    buf.append('\n');
                buf.append(str);
            }
            return buf.toString();
        } catch (IOException e) {
            Log.e("error", "Error opening asset " + name);
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    Log.e("error", "Error closing asset " + name);
                }
            }
        }

        return null;
    }

}

Third, do not forget to initialize your Webview to use JavaScriptInterface:

     //Set JS interface from JS/HTML code execution
     mWebView.addJavascriptInterface(new JavaScriptInterface(), "android");

Fourth, call the android method getFileContents() to load the local resources in your HTML with JavaScript:

       <script type="text/javascript">
          var s = document.createElement('script');
          s.innerHTML = window.android.getFileContents('js/jquery.min.js');
          document.head.appendChild(s);

          //check if jquery is loaded now...
          if(typeof $ != "undefined") {
              $(document).ready(function() {
                    alert("jQuery is loaded!");
             });
          } else {
                alert("jQuery is NOT loaded!");
          }
       </script>

Note: the local resource in this example is in /assets/js/ sub-folder.

like image 36
Bud Damyanov Avatar answered Jan 22 '23 00:01

Bud Damyanov