Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing a JavaScript object using addJavascriptInterface() on Android

Is it possible to pass a JavaScript object from JavaScript to Java using addJavascriptInterface()? Something along these lines:

var javaScriptObject = {"field1":"string1", "field2":"string2"};
JavaScriptInterface.passObject(javaScriptObject);

How would such a call be captured on the Java side? I have no problem setting up the interface to send a string, but when I send an object, I receive null on the Java end.

like image 721
pheelicks Avatar asked Feb 12 '10 09:02

pheelicks


6 Answers

AFAIK, addJavascriptInterface() only works with primitive types and Strings, and so you cannot pass arbitrary Javascript objects.

like image 193
CommonsWare Avatar answered Nov 15 '22 15:11

CommonsWare


This is how I am doing...

In Android...

@JavascriptInterface
public void getJSONTData(String jsonData) {
      try {
             JSONObject data = new JSONObject(jsonData); //Convert from string to object, can also use JSONArray
          } catch (Exception ex) {}
}

In JavaScript...

var obj = { Name : 'Tejasvi', Age: 100};
var str = JSON.stringify(obj);
Android.getJSONTData(str);

As of now, I could not find any other proper way to pass the native JavaScript object directly to JavascriptInterface.

Calling Android.getJSONTData({ Name : 'Tejasvi', Age: 100}) results in null (if parameter type is Object) or undefined (if parameter type is defined as String) in getJSONTData.

like image 25
Tejasvi Hegde Avatar answered Nov 15 '22 16:11

Tejasvi Hegde


I found a solution, using JSON. My Java method returns a JSONArray, on my javascript code I receive this and convert to a javascript vector using JSON.parse(). See the example:

Java:

public class JavaScriptInterface {
Context mContext;
private static int ind=-1;
private static int [] val = { 25, 25, 50, 30, 40, 30, 30, 5, 9 };

public JavaScriptInterface(Context c) {
    mContext = c;
}

@JavascriptInterface
public JSONArray getChartData() {
    String texto = " [ {name: 'valor1', 2007: "+val[(++ind)%9]+"}, "+
                     " {name: 'valor2', 2007: "+val[(++ind)%9]+"}, "+
                     " {name: 'valor3', 2007: "+val[(++ind)%9]+"} ]"; 

    JSONArray jsonar=null;
    try {
        jsonar = new JSONArray(texto);
    } catch (JSONException e) {
        e.printStackTrace();
    }

    return jsonar;
}
}

Now the javascript code:

window.generateData = function() {
        /*var data = [ {name: 'valor1', 2007: 50},
                     {name: 'valor2', 2007: 20},
                     {name: 'valor3', 2007: 30} ];     */
        var data = JSON.parse( Android.getChartData() );
        return data;
    };

The commented code above show how it was when static, and now the data came from the Java code.

It was testes on Android 2.1 and 3.2.

like image 9
Derzu Avatar answered Nov 15 '22 17:11

Derzu


I can run this feature

In Javascript :

var data = {
            'username' : $('#username').val().trim(),
            'password' : $('#password').val().trim(),
            'dns' : $('#dns').val().trim()
        }
        var str = JSON.stringify(data);
        Native.getLoginService(str);

In Android :

@JavascriptInterface
public void getLoginService(String jsonData){
    try{
        JSONObject data = new JSONObject(jsonData);
        String username = data.getString("username");
        String password = data.getString("password");
        String dns = data.getString("dns");

        Log.i("TAG",username + " - " + password + " - " + dns);

    }catch (Exception ex){
        Log.i("TAG","error : " + ex);
    }
}

Good luck with...

like image 7
selçuk doğan Avatar answered Nov 15 '22 15:11

selçuk doğan


I think you can also pass JSONObject and JSONArray. So not only primitive types, but also primitive types stored in a javascript array [0,1,2] or dictionary {one:1, two:2}.

I have NOT verified this in code, just read the docs. Might be using it soon.

like image 2
e mail Avatar answered Nov 15 '22 16:11

e mail


You can't pass JSONObject or JSONArray, but you can send strings with that form and parse them to those types.

Your option is to expose the method using strings and then you can use the JSONObject or JSONArray to parse the string and use it accordingly.

Here is what I did.

@JavascriptInterface
public void passJSON(String array, String jsonObj) throws JSONException
{
    JSONArray myArray = new JSONArray(array);
    JSONObject myObj = new JSONObject(jsonObj);     
    ...

}

where array is '["string1","string2"]' and jsonObj is '{attr:1, attr2:"myName"}'

like image 2
SergioM Avatar answered Nov 15 '22 16:11

SergioM