I have and application built with PhoneGap
, and I'm trying to communicate with Javascript
from native code.
in my DroidGap
extending class:
@Override
public void onCreate(Bundle savedInstanceState) {
Logger.log(oncreate);
super.onCreate(savedInstanceState);
super.init();
super.appView.getSettings().setJavaScriptEnabled(true);
super.appView.getSettings().setSupportZoom(true);
super.appView.getSettings().setBuiltInZoomControls(true);
super.appView.getSettings().setDisplayZoomControls(false);
jsinterface = new CommunicationInterface(this, appView);
super.appView.addJavascriptInterface(jsinterface, communicationinterface);
}
the javascriptinterface:
public class CommunicationInterface {
private WebView mAppView;
private DroidGap mGap;
public CommunicationInterface(DroidGap gap, WebView view) {
mAppView = view;
mGap = gap;
}
public String getTestString() {
return teststring;
}
public void parse(Object o) {
Logger.log(o);
}
}
The Javacript
is located in an external file (I create an HTML file which has this line in the header
: <script type=text/javascript src=scripts.js></script>
)
Scripts.js
:
function sendToInterface() {
alert(alert);
var map = new Object();
(...)
window.communicationinterface.parse(map); //communication js -> android seems to work.
}
I read in other posts that it's possible to communicate between PhoneGap and Android, but thusfar I've not had any success. I did manage to create an alert, but that was with loadUrl(javascript:alert('Alert');)
, but I've also read that you shouldn't do because that's what sendJavascript()
is for (and it causes leaks, reloads page, etc). I've tried to shoot a couple of Strings through the sendJavascript()
method, but to no avail:
sendJavascript(javascript:alert('Alert');)
sendJavascript(javascript:sendToInterface();)
sendJavascript(sendToInterface();)
sendJavascript(window.sendToInterface();)
How to communicate from native -> PhoneGap (or what's wrong with what I already have)? Thusfar other posts and questions haven't helped me with this particular problem.
Read:
- http://www.jumpbyte.com/2012/phonegap-native-to-javascript/
- Phonegap: "processMessage failed" unable to send javascript function (Cordova 2.5.0)
- Communication between Android Java and Phonegap Javascript? (although this is the other direction, but I'm trying to do both)
- http://www.intelligrape.com/blog/2013/01/31/using-sendjavscript-to-inject-javascript-into-android-phonegap-application/
- Phonegap - Android - Calling javascript from native causes leakedwindow
- how to call javascript function from android using phonegap plugin
EDIT
I wrote a working project:
Java part
import org.apache.cordova.DroidGap;
import org.json.JSONException;
import org.json.JSONObject;
import android.os.Bundle;
import android.util.Log;
public class App extends DroidGap {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.loadUrl(file:///sdcard/ds/index.html);
System.out.println(loading from sdcard);
Thread t = new Thread() {
public void run() {
try {
for (int i = 0; i < 3; i++) {
sleep(2000);
sendValue(value + i, another vlaue + i);
}
} catch (Exception e) {
e.printStackTrace();
}
};
};
t.start();
}
public void sendValue(String value1, String value2) {
System.out.println(sendvalue in app);
JSONObject data = new JSONObject();
try {
data.put(value1, value1);
data.put(value2, value2);
} catch (JSONException e) {
Log.e(CommTest, e.getMessage());
}
String js = String.format(window.plugins.appcomm.updateValues('%s');,
data.toString());
this.sendJavascript(js);
}
}
import org.apache.cordova.api.Plugin;
import org.apache.cordova.api.PluginResult;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.util.Log;
public class AppComm extends Plugin{
private static AppComm instance;
public AppComm () {
instance = this;
}
public static AppComm getInstance() {
return instance;
}
@Override
public PluginResult execute(String action, JSONArray args, String callbackId) {
System.out.println(in execute from appcomm);
return null;
}
public void sendValue(String value1, String value2) {
System.out.println(sendvalue in appComm);
JSONObject data = new JSONObject();
try {
data.put(value1, value1);
data.put(value2, value2);
} catch (JSONException e) {
Log.e(CommTest, e.getMessage());
}
String js = String.format(
window.plugins.commtest.updateValues('%s');,
data.toString());
this.sendJavascript(js);
}
}
res/xml/plugins.xml
<plugins>
<plugin name=App value=org.apache.cordova.App/>
<plugin name=Geolocation value=org.apache.cordova.GeoBroker/>
<plugin name=Device value=org.apache.cordova.Device/>
<plugin name=Accelerometer value=org.apache.cordova.AccelListener/>
<plugin name=Compass value=org.apache.cordova.CompassListener/>
<plugin name=Media value=org.apache.cordova.AudioHandler/>
<plugin name=Camera value=org.apache.cordova.CameraLauncher/>
<plugin name=Contacts value=org.apache.cordova.ContactManager/>
<plugin name=File value=org.apache.cordova.FileUtils/>
<plugin name=NetworkStatus value=org.apache.cordova.NetworkManager/>
<plugin name=Notification value=org.apache.cordova.Notification/>
<plugin name=Storage value=org.apache.cordova.Storage/>
<plugin name=Temperature value=org.apache.cordova.TempListener/>
<plugin name=FileTransfer value=org.apache.cordova.FileTransfer/>
<plugin name=Capture value=org.apache.cordova.Capture/>
<plugin name=Battery value=org.apache.cordova.BatteryListener/>
<plugin name=SplashScreen value=org.apache.cordova.SplashScreen/>
<plugin name=AppComm value=com.example.plugin.AppComm/>
</plugins>
cordova.xml
<?xml version=1.0 encoding=utf-8?>
<cordova>
<access origin=.*/> <!-- allow local pages -->
<log level=DEBUG/>
<preference name=classicRender value=true />
</cordova>
Index.html header
<head>
<meta charset=utf-8 />
<meta name=viewport content=width=device-width, initial-scale=1, maximum-scale=1.0 />
<title>
</title>
<link rel=stylesheet href=http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.css />
<script src=http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js>
</script>
<script src=http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.js>
</script>
<script type=text/javascript charset=utf-8 src=cordova.js></script>
<script type=text/javascript charset=utf-8>
var AppComm=function(){};
AppComm.prototype.updateValues=function(a){
var map = new Object();
map[X1] = hallo;
map[X2] = hi;
cordova.exec(null, null, null);
};
cordova.addConstructor(function(){cordova.addPlugin(appcomm,new AppComm)});
</script>
</head>
One of the problems was that javascript was in a separate file (I think that was one of the problems). If it isn't to much to ask, how can I properly call java back, and with what values? How to implement the execute method and how to call it (I'm really bad at JQuery)?