2

I have a problem in my Hybrid Android App.I need to have a WebView with an HTML and in this HTML I have a button.

I have a layout with a WebView and I have a button inside the HTML, I'm trying to launch a second Activity with another screen(also a layout with a WebView) when the user click this button.

My problem is that this button is not launching the second activity.

I'm using Cordova.

This is my layout(pruebas.xml):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<WebView
    android:id="@+id/webview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_below="@+id/textView" />

</LinearLayout>

This is my MainActivity.java:

public class MainActivity extends CordovaActivity{

    WebView wv;

    JavaScriptInterface JSInterface;

    @Override
    public void onCreate(Bundle savedInstanceState){

        super.onCreate(savedInstanceState);

        StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
        StrictMode.setVmPolicy(builder.build());

        setContentView(R.layout.pruebas);
        wv = (WebView)findViewById(R.id.webview);

        wv.getSettings().setJavaScriptEnabled(true);
        wv.getSettings().setDomStorageEnabled(true);
        // register class containing methods to be exposed to JavaScript

        JSInterface = new MainActivity.JavaScriptInterface(this);
        wv.addJavascriptInterface(JSInterface, "JSInterface");

        wv.loadUrl("file:///android_asset/www/description.html");

    }

    public class JavaScriptInterface {
        Context mContext;

        /** Instantiate the interface and set the context */
        JavaScriptInterface(Context c) {
            mContext = c;
        }

        @android.webkit.JavascriptInterface
        public void changeActivity(){
            Intent i = new Intent(MainActivity.this, JavascriptInterfaceActivity.class);
            i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            startActivity(i);
            finish();
        }
    }
}

And this is my second activity (JavascriptInterfaceActivity.java):

public class JavascriptInterfaceActivity extends Activity {

    WebView wv;

    JavaScriptInterface JSInterface;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
        StrictMode.setVmPolicy(builder.build());

        setContentView(R.layout.pruebas);
        wv = (WebView)findViewById(R.id.webview);

        wv.getSettings().setJavaScriptEnabled(true);
        wv.getSettings().setDomStorageEnabled(true);

        JSInterface = new JavaScriptInterface(this);
        wv.addJavascriptInterface(JSInterface, "JSInterface");

        wv.loadUrl("file:///android_asset/www/description-long.html");

    }


    public class JavaScriptInterface {
        Context mContext;

        /** Instantiate the interface and set the context */
        JavaScriptInterface(Context c) {
            mContext = c;
        }

        @android.webkit.JavascriptInterface
        public void changeActivity(){
            Intent i = new Intent(JavascriptInterfaceActivity.this, MainActivity.class);
            i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            startActivity(i);
            finish();
        }
    }
}

This is the description.html, the other HTML (description-long.html) is similar:

<!DOCTYPE html>
<html>
<head>
    <script src='changeactivity.js'></script>

    <meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *">
    <meta name="format-detection" content="telephone=no">
    <meta name="msapplication-tap-highlight" content="no">
    <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
    <link rel="stylesheet" type="text/css" href="css/index.css">
    <title>Main activity</title>
</head>
<body>
<button id='changeactivity'>Changue activity</button>
</body>
</html>

This is my changeactivity.js file in assets/www:

 function displaymessage(){
     JSInterface.changeActivity();
 }

 document.addEventListener('DOMContentReady', function () {
         document.getElementById('changeactivity').addEventListener('click', displaymessage);
 });

Any suggestion? I check these posts:

https://stackoverflow.com/a/10481108/3739382

https://stackoverflow.com/a/31631068/3739382

3
  • have you add this line myWebView.getSettings().setJavaScriptEnabled(true); Commented Mar 30, 2018 at 11:02
  • check this it might help you stackoverflow.com/questions/32911238/… Commented Mar 30, 2018 at 11:03
  • Yes, I have this line in my Activity: wv.getSettings().setJavaScriptEnabled(true); I'm not using 3d effects or similar, I only have a simple HTML. Commented Mar 30, 2018 at 11:33

1 Answer 1

1

Based on the Binding JavaScript documentation

Note: The object that is bound to your JavaScript runs in another thread and not in the thread in which it was constructed.

You are starting the activity on non-UI thread. You should run it on UI thread as follows:

@android.webkit.JavascriptInterface
    public void changeActivity(){
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                 Intent i = new Intent(MainActivity.this, JavascriptInterfaceActivity.class);
                 i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                 startActivity(i);
                 finish();
            }
        });

    }

Alternatively you can also use Handler.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks. I put your code but the problem persist. I also debugged the app but looks like never enter in the changeActivity method, probably fails something in the "connection" between Javascript and the activity.
How about you try <input type="button" id="changeactivity" value="Changue activity" onClick="displaymessage()"> Then put the <script> function displaymessage(){ JSInterface.changeActivity(); } </script> directly in the body? Just to ensure that communication works between Android code and JavaScript
Thanks! Finally I fixed an error in my code and finally is working with your changeActivity() code.

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.