Calling JavaScript Function from Android and Handling Result

In this tutorial I am going to describe JavaScriptInterface  for Calling Android Function from JavaScript i.e., JavaScript Binding to Android.

Setting up WebView
First add JavaScriptInterface to webView as follows. Here "MyAndroid" will be used later to call functions in JavaScriptInterface later.



  webView = (WebView) findViewById(R.id.webView);
  WebSettings webSettings = webView.getSettings();
  webSettings.setJavaScriptEnabled(true);
  webView.addJavascriptInterface(new JavaScriptInterface(this), "MyAndroid");

The JavaScriptInterface Class:

 public class JavaScriptInterface {
     Context mContext;
     JavaScriptInterface(Context c) {
         mContext = c;
     }
     //add other interface methods to be called from JavaScript
}

HTML File:
<html>
  <head>
    <script type="text/javascript">
    function getValue(){
       //return value to Android 
       var val= document.ipForm.userName.value;
       MyAndroid.receiveValueFromJs(val);
    }
    </script>
    <title></title>
  </head>
  <body >
    <form name="ipForm" id="ipForm">
      UserName : <input type="text" name="userName">
      <button type="button" onclick="getValue();">Submit</button>
    </form>
  </body>
</html>

Android part :



The main things to do on Android Code are :

a)Add a Button to Android UI and add onClickListener to it. We will call JavaScript's   getValue() method on onClick event of this Button.
callBtn = (Button) findViewById(R.id.callBtn);
callBtn.setOnClickListener(new OnClickListener() {
    @Override
     public void onClick(View v) {
          //this calls javascript function
          webView.loadUrl("javascript:getValue()");
    }
});


b)Adding Callback function in JavaScriptInterface for MyAndroid.receiveValueFromJs(val):
The value from webpage is contained in variable str which comes as parameter. 
public void receiveValueFromJs(String str) {
//do something useful with str
  Toast.makeText(mContext, "Received Value from JS: " + str,Toast.LENGTH_SHORT).show();
}

Note : Here, The function getValue() is called from both onClick event of android Button and onclick event of html submit button.


In summary, we did the following:

  • First we  registered the interfaces
  • JavaScript function-javascript:getValue() is called on onClick
  • getValue reads the value from form and returns to android by calling the callback function receiveValueFromJs. Here the value is send as parameter.

12 comments :

  1. Hello.

    "Here 'Android' will be used later..." should be "Here 'MyAndroid' will be used later..."

    ReplyDelete
  2. Thank you for the comment. I corrected it.

    ReplyDelete
  3. Hello - thank you for posting this up. It is helping me with my current project at work. I'm a complete Java/JS newbie and got a question.

    If I changed the receiveValueFromJs(String str) to return the str, how would I be able to access value of str in webview.

    Example:
    String tester = webView.loadUrl("javascript:getValue()");

    I get a "Type mismatch: cannot convert from void to String" error. Thanks in advance!

    ReplyDelete
  4. String tester = webView.loadUrl("javascript:getValue()"); doesnot return the value from webpage. Instead, we can get the form value from the callback function. here receiveValueFromJs. You got that error because webView.loadUrl() returns void.

    You should do the following :
    public void receiveValueFromJs(String str) {
    //you get the value from webpage in variable str.
    String tester = str;
    }

    ReplyDelete
  5. Thank you for the followup Ganesh. I should have hovered over the Eclipse error and it states right there that webView.loadUrl() returns a void.

    I know you must be busy so when you have time if you could point me in the right direction on one more thing, it would be appreciated.

    How would I send what is inside String tester of JavaScriptInterface class to the webView that is contained in my main class?

    Thanks for you time and effort in informing people like me how to code.

    ReplyDelete
  6. As you said "How would I send what is inside String tester of JavaScriptInterface class to the webView that is contained in my main class?"
    --> you want to call some functions on JavaScript of your webview with some parameter.

    For this see my earlier blog Calling JavaScript function from Android"

    ReplyDelete
  7. that didn't work on android version 4.0.4 its fine on earlier version

    ReplyDelete
  8. According to Google documentation "Caution: If you've set your targetSdkVersion to 17 or higher, you must add the @JavascriptInterface annotation to any method that you want available to your JavaScript ".
    Taht could solve your problem.

    Source : http://developer.android.com/guide/webapps/webview.html

    ReplyDelete
  9. Where have you loaded html file in your code? I could not get it done.

    ReplyDelete
    Replies
    1. you can put your html file in asset directory and load as follows:

      //webView.loadUrl("file:///android_res/raw/testhtml.html");
      webView.loadUrl("file:///android_asset/testhtml.html");

      for more detail : read the webview related articles given in : http://ganeshtiwaridotcomdotnp.blogspot.com/search/label/Android

      Delete
  10. hello,

    Thank you for the post,
    I want to ask one thing

    Can we use javascript methods and the java methods from the same html file, if yes then how????

    Thanks in advance.

    ReplyDelete
  11. hello

    Thank you for the post.

    There is an already impemented site, which i use to make an app in android using webview.
    There is a button already which on the site works perfectly but does nothing on my app.
    I can understand your code so here is my question:

    Do I need to make a new button in android to use the function of the existing one which is in the website? Like you did here:
    a)Add a Button to Android UI and add onClickListener to it. We will call JavaScript's getValue() method on onClick event of this Button.
    callBtn = (Button) findViewById(R.id.callBtn);
    callBtn.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
    //this calls javascript function
    webView.loadUrl("javascript:getValue()");
    }
    });


    or i can somehow detect the clicking of the button of the website in order to call the function?

    Thank you

    ReplyDelete

Your Comment and Question will help to make this blog better...