Click here to Skip to main content

Android addJavaScriptInterface

Introduction

Hi everyone again. Today I am going to share my experience with the addJavaScriptInterface method in Android. This class basically helps us call any activity method inside your JavaSscript function. Some of the points I want to mention below: 

This article covers the following points: 

  1. Implementation of JavaScriptInterface and the methods.
  2. Using this interface, I am going to bind a textview control.
  3. Source code of my demo app.

Background

Click here to know more about Webview and the addJavascriptInterface method.

Using the Code

I am going to use an eclipse IDE and I suppose that you have some experience in Android development using the Eclipse IDE. I am going to create a new project named JavaScriptInterfaceDemo. After creating it I am going to add user permission for internet in my AndroidManifest.xml file. 

<uses-permission android:name="android.permission.INTERNET"/>

Then I created a folder named www within my asset folder. After that I created a file index.html within the www folder. I have used webview and textview controls in my layout file named main.xml. My main.xml code is given below.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    <WebView
        android:id="@+id/webView1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1" />
    
    <LinearLayout 
	    android:layout_width="fill_parent"
	    android:layout_height="fill_parent"
	    android:orientation="vertical"
	    android:layout_weight="1">
     <TextView
        
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"       
        android:textAppearance="?android:attr/textAppearanceLarge" />
   </LinearLayout>
</LinearLayout>

In the main.xml file, I have used a parent layout. It's a linear layout and within this layout I have used some child controls and layout which are known as webview, textview controls and linear layout.

Now I am going to write a few more lines in my JavaScriptInterfaceDemoActivity.java class. Let me show my code.

package my.demo;
import my.demo.R;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.webkit.WebView;
import android.widget.TextView;
import android.widget.Toast;


public class JavaScriptInterfaceDemoActivity extends Activity {
	private WebView Wv;
	private TextView myTextView;	
	final Handler myHandler = new Handler();
	
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
       
        setContentView(R.layout.main);
        Wv = (WebView)findViewById(R.id.webView1);
        myTextView = (TextView)findViewById(R.id.textView1);        
        final JavaScriptInterface myJavaScriptInterface
     	= new JavaScriptInterface(this);    	 
    	 
        Wv.getSettings().setLightTouchEnabled(true);
        Wv.getSettings().setJavaScriptEnabled(true);
        Wv.addJavascriptInterface(myJavaScriptInterface, "AndroidFunction");
        Wv.loadUrl("file:///android_asset/www/index.html"); 
    }
    
    public class JavaScriptInterface {
		Context mContext;

	    JavaScriptInterface(Context c) {
	        mContext = c;
	    }
	    
	    public void showToast(String webMessage){	    	
	    	final String msgeToast = webMessage;	    	
	    	 myHandler.post(new Runnable() {
	             @Override
	             public void run() {
	                 // This gets executed on the UI thread so it can safely modify Views
	                 myTextView.setText(msgeToast);
	             }
	         });

	       Toast.makeText(mContext, webMessage, Toast.LENGTH_SHORT).show();
	    }
    }
}

In my Java class file, I have written some code in the oncreate method. In this method, I find my webview and textview controls using the findViewById method. Then I create a JavaScriptInterface class. This class has a constructor and that constructor initializes the Context class. Now suddenly a question raises in your mind, what is a Context Class?

Context Class is an abstract class whose implementation is provided by the Android system. It allows access to application-specific resources and classes, as well as up-calls for application-level operations such as launching activities, broadcasting and receiving intents, etc.

After the initialization of the constructor, I create a method named showToast with a string parameter. This method has a variable msgeToast string and then I created a Handler named myHandler. Click here to know more about Handlers. This handler has a Post method. In the method declaration, I create a new instance of the Runnable thread class and inside this class I override a run method. This run method sets the value for the textview control.

Now I create an instance of my JavaScriptInterface class in my OnCreate method. 

final JavaScriptInterface myJavaScriptInterface = new JavaScriptInterface(this);

After the initialization of the JavaScriptInterface class, I added one more line in my OnCreate method:

Wv.addJavascriptInterface(myJavaScriptInterface, "AndroidFunction");

Webview provides the addJavascriptInterface method. This method contains two parameters:

  1. The class instance to bind to JavaScript.
  2. The name to be used to expose the instance in JavaScript.

For webview, we need to call some settings to enable the JavaScript.

Wv.getSettings().setJavaScriptEnabled(true);

And finally, you need to provide a web URL in your web view:

Wv.loadUrl("file:///android_asset/www/index.html");

Then I created an HTML file named index.html. This HTML file has a textbox and a Submit button. The HTML file code is given below:

<!DOCTYPE >
<html xmlns="http://www.w3.org/1999/xhtml" debug="true">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <meta name="viewport" 
          content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
        <meta name="apple-mobile-web-app-capable" content="yes">
        <meta name="viewport" content="target-densitydpi=device-dpi" />
        <script type="text/javascript">
           function init()
           {
        	   var testVal = document.getElementById('mytextId').value;
        	   AndroidFunction.showToast(testVal);
           }
        </script>
    </head>
    <body>        
        <div style="float: left;width: 50%;">
           <input type="text" style="width: 180px;" 
                   name="myText" id="mytextId" />
           
        </div>
        <div style="clear: both;height: 3px;"> </div>
        <div>
          <input value="submit" type="button" name="submit" 
            id="btnSubmit" onclick="javascript:return init();" /> 
        </div>  
    </body>
</html>

This HTML file has a JavaScript function named init. This function calls the activity method.

AndroidFunction.showToast(testVal); 

AndroidFunction is the same name used to expose the instance in JavaScript. We have already given this name in our addJavascriptInterface method. 

Now finally run your app.

I have also added a toast message in my view.

Points of Interest 

This is a very good feature provided by a addJavascriptInterface method. But you must be more careful when you implement this approach. Otherwise the hacker can inject bad HTML inside code. This is the good thing that I have learned during my development phase. I hope you guys will enjoy it and it will help you out in your problems.  

Conclusion  

For more details on the source code, please download the source code from the link at the top of this article. The source code is easy and well commented.

Hope this tutorial is useful.

 
You must Sign In to use this message board.
Search 
Per page   
QuestionCan I use this to double click?
Member 9589497 at 8-Dec-12 13:34
Thanks Sushil, this was a very informative article. Do you think I can use this method to send a double-click event from Android? My company has a web page that uses Javascript Double-Click for certain items and I am have a terrible time trying to figure out how to SEND a double-click even from Android to open those items. I can listen for a double-tap event just fine, but sending it is a different story.
AnswerRe: Can I use this to double click?
Sushil Sh. at 11-Dec-12 18:26
Yes, You can ,It is possible to handle the javascript method from your android code also.If you want then i can create a sample code for you and send it to you.
AnswerRe: Can I use this to double click?
Sushil Sh. at 13-Dec-12 0:03
Yes You Can,The example that i have written ,Just read it again ,It's for vice verse. It's means you can call the android method from javascript code as well you can also call the javascript method from your's android code.
 
In case ,If you want any sample code then i will develop it also. Smile | :)
GeneralRe: Can I use this to double click?
Mark-In-Md at 13-Dec-12 3:15
Excellent, Thank you. I am trying to write an app that will allow the user to double-click on an item in a browser. Unfortunately the Javascript site in question is password protected, but I found this site which has a Javascript double-click link that works the same way. If you can show me the code for a very small webview app that will allow the user to activate that double-click link I would be VERY grateful. I can even sned a few $$ your way through PayPal if it all works out.
 
Please continue this conversation via email.
QuestionSome javascript binding history
Lorenzo H. Martín at 14-Jun-12 21:12
Hi,
 
I've been following this binding technologies for a while. Checking them in several platforms and OSs. And after a trouble happened a year ago in Android binding using addjavascript interface, when Google launched a new 2.3.x OS versión (With some kind apologies from Google and some patches too), I realized that it's quite dangerous relying in a technique that it's clearly against the interests of the Google Market. The same thing happens on every not-so-open OSs. Think about having developped a lot of javascript software and then addjavascript interface (or its equivalent for another OS) suddenly disappears for a new versión of your OS. And you lose all access downwards to LLOS features.
This article is quite interesting. But I think this is not the solution for a serious javascript developer and there are other ways to do the same not so far away.
 
Rgds,
AnswerRe: Some javascript binding history
Sushil Sh. at 18-Jun-12 19:45
Hi,
 
Thanks for your vote.I am new to android development, But it's a very interesting thing that i have found during the development.I thing ,If you are going to create HTML part also,then you can follow same approach.Otherwise, You must be very careful.There might be more approaches,But we need to figure out.
GeneralMy vote of 5
Anil Sh at 12-Jun-12 20:54
My Vote of 5. Thanks a lot, really nice and informative article. Very helpful.
GeneralMy vote of 5
akhi0gupta007 at 12-Jun-12 19:38
Thanks, great examples
GeneralMy vote of 2
Selvin at 12-Jun-12 3:18
nothing more than we already have http://developer.android.com/guide/webapps/webview.html#BindingJavaScript
GeneralRe: My vote of 2
Sushil Sh. at 12-Jun-12 7:20
Thanks for your vote Selvin.But the thing is that set the textview control text.I struggled lot,Then I found this solution using a handler n all stuff.For toast implementation was easy.But the rest things are not easy to implement at-least for me.

Last Updated 11 Dec 2012 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2013
Full site