mirror of
https://github.com/apache/cordova-android.git
synced 2025-02-26 12:03:28 +08:00
Add XHR-based callbacks from Java to JavaScript.
This commit is contained in:
parent
4b3255e4fd
commit
5bdad8c0ca
48
framework/assets/js/phonegap.js.base
Normal file → Executable file
48
framework/assets/js/phonegap.js.base
Normal file → Executable file
@ -67,6 +67,9 @@ PhoneGap.addConstructor = function(func) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Start listening for callbacks from Java
|
||||||
|
PhoneGap.JSCallback();
|
||||||
|
|
||||||
// all constructors run, now fire the deviceready event
|
// all constructors run, now fire the deviceready event
|
||||||
var e = document.createEvent('Events');
|
var e = document.createEvent('Events');
|
||||||
e.initEvent('deviceready');
|
e.initEvent('deviceready');
|
||||||
@ -133,3 +136,48 @@ PhoneGap.run_command = function() {
|
|||||||
document.location = url;
|
document.location = url;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal function that uses XHR to call into PhoneGap Java code and retrieve
|
||||||
|
* any JavaScript code that needs to be run. This is used for callbacks from
|
||||||
|
* Java to JavaScript.
|
||||||
|
*/
|
||||||
|
PhoneGap.JSCallback = function() {
|
||||||
|
var xmlhttp = new XMLHttpRequest();
|
||||||
|
|
||||||
|
// Callback function when XMLHttpRequest is ready
|
||||||
|
xmlhttp.onreadystatechange=function(){
|
||||||
|
if(xmlhttp.readyState == 4){
|
||||||
|
|
||||||
|
// If callback has JavaScript statement to execute
|
||||||
|
if (xmlhttp.status == 200) {
|
||||||
|
|
||||||
|
var msg = xmlhttp.responseText;
|
||||||
|
setTimeout(function() {
|
||||||
|
try {
|
||||||
|
var t = eval(msg);
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
console.log("JSCallback Error: "+e);
|
||||||
|
}
|
||||||
|
}, 1);
|
||||||
|
setTimeout(PhoneGap.JSCallback, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If callback ping (used to keep XHR request from timing out)
|
||||||
|
else if (xmlhttp.status == 404) {
|
||||||
|
setTimeout(PhoneGap.JSCallback, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If error, restart callback server
|
||||||
|
else {
|
||||||
|
console.log("JSCallback Error: Request failed.");
|
||||||
|
CallbackServer.restartServer();
|
||||||
|
setTimeout(PhoneGap.JSCallback, 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
xmlhttp.open("GET", "http://127.0.0.1:"+CallbackServer.getPort()+"/" , true);
|
||||||
|
xmlhttp.send();
|
||||||
|
}
|
||||||
|
@ -9,46 +9,97 @@ import android.hardware.SensorManager;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.webkit.WebView;
|
import android.webkit.WebView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class listens to the compass sensor and calls navigator.compass.setHeading(heading)
|
||||||
|
* method in Javascript every sensor change event it receives.
|
||||||
|
*/
|
||||||
public class CompassListener implements SensorEventListener{
|
public class CompassListener implements SensorEventListener{
|
||||||
WebView mAppView;
|
|
||||||
Context mCtx;
|
public static int STOPPED = 0;
|
||||||
Sensor mSensor;
|
public static int STARTING = 1;
|
||||||
|
public static int RUNNING = 2;
|
||||||
|
public static int ERROR_FAILED_TO_START = 3;
|
||||||
|
|
||||||
private SensorManager sensorManager;
|
WebView mAppView; // WebView object
|
||||||
|
DroidGap mCtx; // Activity (DroidGap) object
|
||||||
|
|
||||||
|
int status; // status of listener
|
||||||
|
|
||||||
|
private SensorManager sensorManager;// Sensor manager
|
||||||
|
Sensor mSensor; // Compass sensor returned by sensor manager
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param appView
|
||||||
|
* @param ctx The Activity (DroidGap) object
|
||||||
|
*/
|
||||||
CompassListener(WebView appView, Context ctx)
|
CompassListener(WebView appView, Context ctx)
|
||||||
{
|
{
|
||||||
mCtx = ctx;
|
this.mCtx = (DroidGap)ctx;
|
||||||
mAppView = appView;
|
this.mAppView = appView;
|
||||||
sensorManager = (SensorManager) mCtx.getSystemService(Context.SENSOR_SERVICE);
|
this.sensorManager = (SensorManager) mCtx.getSystemService(Context.SENSOR_SERVICE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start listening for compass sensor.
|
||||||
|
*
|
||||||
|
* @return status of listener
|
||||||
|
*/
|
||||||
|
public int start() {
|
||||||
|
|
||||||
public void start()
|
// Get accelerometer from sensor manager
|
||||||
{
|
|
||||||
List<Sensor> list = this.sensorManager.getSensorList(Sensor.TYPE_ORIENTATION);
|
List<Sensor> list = this.sensorManager.getSensorList(Sensor.TYPE_ORIENTATION);
|
||||||
if (list.size() > 0)
|
|
||||||
{
|
// If found, then register as listener
|
||||||
|
if (list.size() > 0) {
|
||||||
this.mSensor = list.get(0);
|
this.mSensor = list.get(0);
|
||||||
this.sensorManager.registerListener(this, this.mSensor, SensorManager.SENSOR_DELAY_NORMAL);
|
this.sensorManager.registerListener(this, this.mSensor, SensorManager.SENSOR_DELAY_NORMAL);
|
||||||
|
this.status = CompassListener.STARTING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If error, then set status to error
|
||||||
|
else {
|
||||||
|
this.status = CompassListener.ERROR_FAILED_TO_START;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.status;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stop()
|
/**
|
||||||
{
|
* Stop listening to compass sensor.
|
||||||
this.sensorManager.unregisterListener(this);
|
*/
|
||||||
|
public void stop() {
|
||||||
|
if (this.status != CompassListener.STOPPED) {
|
||||||
|
this.sensorManager.unregisterListener(this);
|
||||||
|
}
|
||||||
|
this.status = CompassListener.STOPPED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when listener is to be shut down and object is being destroyed.
|
||||||
|
*/
|
||||||
|
public void destroy() {
|
||||||
|
this.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onAccuracyChanged(Sensor sensor, int accuracy) {
|
public void onAccuracyChanged(Sensor sensor, int accuracy) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sensor listener event.
|
||||||
|
*
|
||||||
|
* @param SensorEvent event
|
||||||
|
*/
|
||||||
public void onSensorChanged(SensorEvent event) {
|
public void onSensorChanged(SensorEvent event) {
|
||||||
|
|
||||||
// We only care about the orientation as far as it refers to Magnetic North
|
// We only care about the orientation as far as it refers to Magnetic North
|
||||||
float heading = event.values[0];
|
float heading = event.values[0];
|
||||||
mAppView.loadUrl("javascript:navigator.compass.setHeading(" + heading + ")");
|
|
||||||
|
this.status = CompassListener.RUNNING;
|
||||||
|
|
||||||
|
// TODO This is very expensive to process every event. Should this use polling from JS instead?
|
||||||
|
mCtx.sendJavascript("navigator.compass.setHeading(" + heading + ");");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,6 +72,7 @@ public class DroidGap extends Activity {
|
|||||||
private CryptoHandler crypto;
|
private CryptoHandler crypto;
|
||||||
private BrowserKey mKey;
|
private BrowserKey mKey;
|
||||||
private AudioHandler audio;
|
private AudioHandler audio;
|
||||||
|
private CallbackServer callbackServer;
|
||||||
|
|
||||||
private Uri imageUri;
|
private Uri imageUri;
|
||||||
|
|
||||||
@ -185,10 +186,38 @@ public class DroidGap extends Activity {
|
|||||||
if (accel != null) {
|
if (accel != null) {
|
||||||
accel.destroy();
|
accel.destroy();
|
||||||
}
|
}
|
||||||
|
if (launcher != null) {
|
||||||
|
|
||||||
|
}
|
||||||
|
if (mContacts != null) {
|
||||||
|
|
||||||
|
}
|
||||||
|
if (fs != null) {
|
||||||
|
|
||||||
|
}
|
||||||
|
if (netMan != null) {
|
||||||
|
|
||||||
|
}
|
||||||
|
if (mCompass != null) {
|
||||||
|
mCompass.destroy();
|
||||||
|
}
|
||||||
|
if (crypto != null) {
|
||||||
|
|
||||||
|
}
|
||||||
|
if (mKey != null) {
|
||||||
|
|
||||||
|
}
|
||||||
|
if (audio != null) {
|
||||||
|
|
||||||
|
}
|
||||||
|
if (callbackServer != null) {
|
||||||
|
callbackServer.destroy();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bindBrowser(WebView appView)
|
private void bindBrowser(WebView appView)
|
||||||
{
|
{
|
||||||
|
callbackServer = new CallbackServer();
|
||||||
gap = new Device(appView, this);
|
gap = new Device(appView, this);
|
||||||
accel = new AccelBroker(appView, this);
|
accel = new AccelBroker(appView, this);
|
||||||
launcher = new CameraLauncher(appView, this);
|
launcher = new CameraLauncher(appView, this);
|
||||||
@ -211,7 +240,7 @@ public class DroidGap extends Activity {
|
|||||||
appView.addJavascriptInterface(crypto, "GapCrypto");
|
appView.addJavascriptInterface(crypto, "GapCrypto");
|
||||||
appView.addJavascriptInterface(mKey, "BackButton");
|
appView.addJavascriptInterface(mKey, "BackButton");
|
||||||
appView.addJavascriptInterface(audio, "GapAudio");
|
appView.addJavascriptInterface(audio, "GapAudio");
|
||||||
|
appView.addJavascriptInterface(callbackServer, "CallbackServer");
|
||||||
|
|
||||||
if (android.os.Build.VERSION.RELEASE.startsWith("1."))
|
if (android.os.Build.VERSION.RELEASE.startsWith("1."))
|
||||||
{
|
{
|
||||||
@ -227,6 +256,25 @@ public class DroidGap extends Activity {
|
|||||||
{
|
{
|
||||||
appView.loadUrl(url);
|
appView.loadUrl(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send JavaScript statement back to JavaScript.
|
||||||
|
*
|
||||||
|
* @param message
|
||||||
|
*/
|
||||||
|
public void sendJavascript(String statement) {
|
||||||
|
System.out.println("DroidGap.sendResponse("+statement+")");
|
||||||
|
this.callbackServer.sendJavascript(statement);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the port that the callback server is listening on.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int getPort() {
|
||||||
|
return this.callbackServer.getPort();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user