8

I am trying to use a webview with an input box, take the string, and pass it to a second activity. For some reason, the button is not doing anything and I get the error:

Uncaught TypeError: Object [object Object] has no method 'changeActivity' at file:///android_asset/www/index.js:3

So my HTML says this:

 <input id="name" value="" />&nbsp;&nbsp;&nbsp;
<button onclick="checkMovie()"> Check it! </button>

my JS says this:

    function checkMovie() {
var movieName = document.getElementById('name').value;
webapi.changeActivity(movieName);}

and my Android code says this:

public class MainActivity extends Activity implements OnClickListener {
// Setting up known variables
JavaScriptInterface JSInterface;

Button find;

@SuppressLint("SetJavaScriptEnabled")
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // changing main layout to show the splash first
    setContentView(R.layout.activity_main);
    // Tie my webviews and set up the webview to handle JS
    WebView webView = (WebView) findViewById(R.id.webView);
    webView.getSettings().setJavaScriptEnabled(true);
    // Expecting UI
    webView.setWebChromeClient(new WebChromeClient());
    // allowing to inject Java objects into a page's JavaScript
    webView.addJavascriptInterface(new JavaScriptInterface(this), "webapi");
    // Load the local file
    webView.loadUrl("file:///android_asset/www/index.html");

    find = new Button(MainActivity.this);
    find.setOnClickListener(this);

    WebSettings ws = webView.getSettings();
    ws.setJavaScriptEnabled(true);
    // Add the interface to record javascript events
    webView.addJavascriptInterface(find, "find");

}

public class JavaScriptInterface {
    Context mContext;



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

    // Call the function changeActivity defined in my JS of my HTML
    public void changeActivity(String movieName) {
        // Call the Movie App and store the intent to pass it onto the app.
        Log.e("XXXXXXXXXXXXXXX", "X==========>" + movieName);
        Intent i = new Intent(MainActivity.this, second.class);
        i.putExtra("movie_name", movieName);
        startActivity(i);
    }

}

@Override
public void onClick(View v) {
    // TODO Auto-generated method stub

    if (v.equals(find)) {
        Log.e("XXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXX");

    }
}

}

user3121402
  • 81
  • 1
  • 3
  • Where is "changeActivity()" function in your index.js file? Can you please the whole js file code. – Siddharth_Vyas Dec 20 '13 at 04:16
  • Thanks for your comment... That is all my js file.. Am I missing something.. Some folks say it works fine running 4.1.1 I am on 4.2.2 – user3121402 Dec 20 '13 at 04:52
  • did you find out the solution for your issue? I had the same problem and just solved. Can share information if you need it anymore. – Lisitso Apr 16 '14 at 13:41

3 Answers3

13

The problem is exactly that. Since you run on 4.2.2 you have to set the @JavascriptInterface annotation on top of your changeActivity method and on any other javascript methods you call in your android code.

@JavascriptInterface
public void changeActivity(String movieName) {
    ...

This is necessary for Android 4.2 or higher.

Follow this link to read more.

Community
  • 1
  • 1
goseib
  • 737
  • 3
  • 12
  • 24
  • 1
    Did this actually break existing apps? Cause I have an app in production where the javascript buttons suddenly stopped working, and I can't find any other explanation. – Nilzor May 08 '14 at 09:05
  • See http://stackoverflow.com/questions/6271485/android-proguard-javascript-interface-fail. – CoolMind Apr 13 '16 at 10:41
5

First on Android 4.2 and higher version, make sure you added the @JavascriptInterface annotation.

Then if you find it stopped working on release(production) mode, it is because of the proguard.

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
# -keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}
Ryan Hoo
  • 360
  • 7
  • 19
  • Thanks. For a better understanding see http://stackoverflow.com/questions/6271485/android-proguard-javascript-interface-fail. – CoolMind Apr 13 '16 at 10:41
2

if the device is 4.2.2, you have to set the annotation @JavascriptInterface. But unfortunately, this interface is not existing in the SDK before 4.2.2.

for this case, you have two options:

  1. change the target of your app, from 4.0/4.1 to 4.2

  2. if you won't to change the target, create a java file android/webkit/JavascriptInterface.java in your own source code and copy the content from 4.2 SDK

WilliamS
  • 143
  • 1
  • 9