3

I've read many posts but I can't get my Android app call a Javascript function. This is what I have

public class BorrameActivity extends AppCompatActivity {

    private static BorrameActivity.MyJavaScriptInterface myJavaScriptInterface;
    private static WebView webView;

    public class MyJavaScriptInterface {
        Context mContext;

        MyJavaScriptInterface(Context c) {
            mContext = c;
        }

        @android.webkit.JavascriptInterface
        public void doEchoTest(String echo){
            Log.e("printer", echo);
            Toast toast = Toast.makeText(mContext, echo, Toast.LENGTH_SHORT);
            toast.show();
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_borrame);

        myJavaScriptInterface = new BorrameActivity.MyJavaScriptInterface(this);
        webView = (WebView) findViewById(R.id.mybrowserAuthorise);
        webView.getSettings().setJavaScriptEnabled(true);
        webView.addJavascriptInterface(myJavaScriptInterface, "JSInterface");
        webView.loadUrl("file:///android_asset/loginProtocol.html");
        //webView.loadUrl("javascript:JSInterface.doEchoTest('test')"); // THIS WORKS!!
        webView.loadUrl("javascript:testEcho()"); // THIS DOES NOT WORK
    }
}

This works when I execute

webView.loadUrl("javascript:JSInterface.doEchoTest('test')");

But it doesn't work when the Javascript function is in loginProtocol.html:

webView.loadUrl("javascript:testEcho()");

Where

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width; user-scalable=0;" />
    <title></title>
</head>
<body style="visibility:visible">
    <!--    Used for debugging -->
    <h1>HELLO</h1>

    <script>
        function testEcho(){
               JSInterface.doEchoTest('This does not get printed in Android Log');
        }
    </script>
</body>
</html>

and

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.sedicii.app.sedicii.BorrameActivity">

    <WebView
        android:id="@+id/mybrowserAuthorise"
        android:layout_width="353dp"
        android:layout_height="442dp"/>

</LinearLayout>

The WebView seems to be loading correctly (I can see the HELLO from loginProtocol.html on the Android screen).

What am I missing?

SOLUTION I have to wait until the HTML page is loaded. Thanks @KosWarm

webView.setWebViewClient(new WebViewClient() {
    public void onPageFinished(WebView view, String url) {
        webView.loadUrl("javascript:testEcho()");
    }
});
1
  • Btw., I have also tried with window.JSInterface.doEchoTest('This does not get printed in Android Log'); and it doesn't work either Commented Mar 7, 2017 at 17:46

2 Answers 2

2

I think you just need to give parameter to your loadUrl method:

webView.loadUrl("javascript:testEcho('Hello World!')");

and your javascript function must look like:

function testEcho(testHello){
 window.JSInterface.doEchoTest(testHello);
}
Sign up to request clarification or add additional context in comments.

Comments

1

You execute the method loadUrl twice At the second execution, the first page is closed, so its script can not be executed

The following page code works

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width; user-scalable=0;" />
    <title></title>
</head>
<body style="visibility:visible">
<!--    Used for debugging -->
<h1>HELLO</h1>

<script>
        function testEcho(){
               JSInterface.doEchoTest('This does not get printed in Android Log');
        }
        testEcho() //added this line
    </script>
</body>
</html>

Update

from this place Calling Javascript method from within webview in Android

rewrite Activity onCrete method as

        myJavaScriptInterface = new MyJavaScriptInterface(this);
        webView = (WebView) findViewById(R.id.mybrowserAuthorise);
        webView.getSettings().setJavaScriptEnabled(true);
        webView.addJavascriptInterface(myJavaScriptInterface, "JSInterface");
        webView.loadUrl("file:///android_asset/loginProtocol.html");
        webView.setWebViewClient(new WebViewClient() {
        public void onPageFinished(WebView view, String url) {
            webView.loadUrl("javascript:testEcho()");
        }
        });

4 Comments

Yes, testEcho() is executed now. But with this approach it always gets executed when the HTML page is loaded, also when I remove it's call from the Android Java code webView.loadUrl("javascript:testEcho()");. I would like to actually call the JS function from Android, not to load an html that automatically executes the function. Is calling loadUrl twice bad?
Maybe this is what you were looking for stackoverflow.com/questions/35906557/…
The loadUrl method is called asynchronously, so the second call was executed before the page was loaded. Because of what the script was not executed
OMG @KosWarm, you are right! I need to wait for the html page to be loaded in order to cal the JS function!!! I read so many posts, but not that one, THANKS!!!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.