How we can execute a javascript function and get a return value in our android application?

18,340

Solution 1

you can use mWebView.loadUrl("javascript:checkName"); to call the method...

Then you can use addJavascriptInterface() to add a Java object to the Javascript environment. Have your Java script call a method on that Java object to supply its "return value".

EDIT1: Or you can use following hack:

Add this Client to your WebView:

final class MyWebChromeClient extends WebChromeClient {
        @Override
        public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
            Log.d("LogTag", message);
            result.confirm();
            return true;
        }
    }

Now in your java script call do:

webView.loadUrl("javascript:alert(functionThatReturnsSomething)");

Now in the onJsAlert call "message" will contain the returned value.

Edit2:

So it does not work if we call javascript method just after call to load the URL since the page loads take time. So I created a test program to test that...

Following is my html file (named test.html) store in the assets folder:

<html>
<head>
<script language="javascript">
    function fieldsOnDelete(message) {
        alert("i am called with " + message);
        window.myjava.returnValue(message + " JIJO");
    }
</script>
<title>iSales android</title>


</head>
<body></body>
</html>
</body>
</html>

Following is my java class that would get that i would add to java script as interface and it would receive the return value:

public class MyJS {

    public void returnValue(String string){
        Log.d(this.getClass().getSimpleName(), string);
    }

}

And following is my activity class:

public class CheckWebView extends Activity {

    private WebView webView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_check_web_view);
        webView = (WebView) findViewById(R.id.webview);

        webView.setWebChromeClient(new WebChromeClient() {
            @Override
            public void onConsoleMessage(String message, int lineNumber,
                    String sourceID) {
                super.onConsoleMessage(message, lineNumber, sourceID);
                Log.d(this.getClass().getCanonicalName(), "message " + message
                        + "   :::line number " + lineNumber + "   :::source id "
                        + sourceID);
            }

            @Override
            public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
                // TODO Auto-generated method stub

                onConsoleMessage(consoleMessage.message(),
                        consoleMessage.lineNumber(), consoleMessage.sourceId());

                Log.d(this.getClass().getCanonicalName(), "message::::: "
                        + consoleMessage.message());

                return super.onConsoleMessage(consoleMessage);
            }
        });

        webView.addJavascriptInterface(new MyJS(), "myjava");
        webView.getSettings().setJavaScriptEnabled(true);
        webView.getSettings().setPluginsEnabled(true);
        webView.getSettings().setAllowFileAccess(true);

        webView.loadUrl("file:///android_asset/test.html");

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_check_web_view, menu);
        return true;
    }

    /* (non-Javadoc)
     * @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)
     */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        webView.loadUrl("javascript:fieldsOnDelete('name');");
        return super.onOptionsItemSelected(item);
    }

}

The key here is that there should be some time interval between the call to load html file from assets folder and the call to javascript:method. Here I am calling it from onOptionsItemSelected and it is working fine.. if I move the webView.loadUrl("javascript:fieldsOnDelete('name');"); to the end of the onCreate() method the it shows the error that it can not find fieldsOnDelete() method...

Hope it Helps...

EDIT3:

Replace following in your code

webView.loadUrl("javascript:alert(javascript:fieldsOnDelete())");

with

webView.loadUrl("javascript:alert(fieldsOnDelete())");

and try...

Solution 2

In Android KitKat there is a new method evaluateJavascript that has a callback for a return value. The callback returns a JSON value, object or array depending on what you return.

        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            // In KitKat+ you should use the evaluateJavascript method
            mWebView.evaluateJavascript(javascript, new ValueCallback<String>() {
                @TargetApi(Build.VERSION_CODES.HONEYCOMB)
                @Override
                public void onReceiveValue(String s) {
                    JsonReader reader = new JsonReader(new StringReader(s));

                    // Must set lenient to parse single values
                    reader.setLenient(true);

                    try {
                        if(reader.peek() != JsonToken.NULL) {
                            if(reader.peek() == JsonToken.STRING) {
                                String msg = reader.nextString();
                                if(msg != null) {
                                    Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
                                }
                            }
                        }
                    } catch (IOException e) {
                        Log.e("TAG", "MainActivity: IOException", e);
                    } finally {
                        try {
                            reader.close();
                        } catch (IOException e) {
                            // NOOP
                        }
                    }
                }
            });
        }

You can see a full example here: https://github.com/GoogleChrome/chromium-webview-samples/tree/master/jsinterface-example

Share:
18,340
Admin
Author by

Admin

Updated on June 09, 2022

Comments

  • Admin
    Admin almost 2 years

    How we can execute a javascript function and get a return value in our android appplication ?

    We want to execute a javascript on a button press event, we need to pass parameters to the script and get return values, So we are using "WebChromeClient" to implement this, But we got Exception is "SyntaxError: Parse error at undefined:1"

    Following is my code

    import android.app.Activity;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.widget.Button;
    import android.webkit.JsResult;
    import android.webkit.WebChromeClient;
    import android.webkit.WebSettings;
    import android.webkit.WebView;
    
    public class FirstTab extends Activity 
    {
    
    
        private WebView webView;
    
        public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                 setContentView(R.layout.regis);
    
                try{
    
                    webView = (WebView) findViewById(R.id.webView1);
                    webView.getSettings().setJavaScriptEnabled(true);
                    webView.setWebChromeClient(new MyWebChromeClient());
                    String customHtml = "<html><head><title>iSales</title><script type=\"text/javascript\"> function fieldsOnDelete(){ var x=123; return \"JIJO\"; } </script></head><body>hi</body></html>";
                    webView.loadData(customHtml, "text/html","UTF-8");  
    
                    }catch(Exception e)
                    {
                         Log.v("JAC LOG",e.toString());
                    }
    
            }
        public void onResume()
        {
            super.onResume();
    
                final Button button = (Button) findViewById(R.id.button1);
                 button.setOnClickListener(new View.OnClickListener() {
                 public void onClick(View v) {
                     try{
                        webView.loadUrl("javascript:alert(javascript:fieldsOnDelete())");
                     }
                     catch(Exception e)
                     {
                         Log.v("JAC LOG",e.toString());
    
                     }
                  } 
                 });
        }
    
    
        final class MyWebChromeClient extends WebChromeClient {
            @Override
            public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
    
            Log.v("LogTag", message);
              result.confirm();
              return true;
            }
        }
    
    
    }