mirror of
https://github.com/apache/cordova-android.git
synced 2025-02-27 04:42:51 +08:00
[CB-463] rewrite of accel plugin
This commit is contained in:
parent
0850229c9f
commit
71e47aa772
@ -18,7 +18,11 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.cordova;
|
package org.apache.cordova;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.apache.cordova.api.CordovaInterface;
|
import org.apache.cordova.api.CordovaInterface;
|
||||||
import org.apache.cordova.api.Plugin;
|
import org.apache.cordova.api.Plugin;
|
||||||
@ -32,6 +36,8 @@ import android.hardware.Sensor;
|
|||||||
import android.hardware.SensorEvent;
|
import android.hardware.SensorEvent;
|
||||||
import android.hardware.SensorEventListener;
|
import android.hardware.SensorEventListener;
|
||||||
import android.hardware.SensorManager;
|
import android.hardware.SensorManager;
|
||||||
|
import android.location.Location;
|
||||||
|
import android.util.Log;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -40,20 +46,20 @@ import android.content.Context;
|
|||||||
*/
|
*/
|
||||||
public class AccelListener extends Plugin implements SensorEventListener {
|
public class AccelListener extends Plugin implements SensorEventListener {
|
||||||
|
|
||||||
public static int STOPPED = 0;
|
public static int STOPPED = 0;
|
||||||
public static int STARTING = 1;
|
public static int STARTING = 1;
|
||||||
public static int RUNNING = 2;
|
public static int RUNNING = 2;
|
||||||
public static int ERROR_FAILED_TO_START = 3;
|
public static int ERROR_FAILED_TO_START = 3;
|
||||||
|
|
||||||
public float TIMEOUT = 30000; // Timeout in msec to shut off listener
|
private float x,y,z; // most recent acceleration values
|
||||||
|
private long timestamp; // time of most recent value
|
||||||
|
private int status; // status of listener
|
||||||
|
|
||||||
float x,y,z; // most recent acceleration values
|
private SensorManager sensorManager; // Sensor manager
|
||||||
long timestamp; // time of most recent value
|
private Sensor mSensor; // Acceleration sensor returned by sensor manager
|
||||||
int status; // status of listener
|
|
||||||
long lastAccessTime; // time the value was last retrieved
|
|
||||||
|
|
||||||
private SensorManager sensorManager;// Sensor manager
|
private HashMap<String, String> watches = new HashMap<String, String>();
|
||||||
Sensor mSensor; // Acceleration sensor returned by sensor manager
|
private List<String> callbacks = new ArrayList<String>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an accelerometer listener.
|
* Create an accelerometer listener.
|
||||||
@ -66,169 +72,149 @@ public class AccelListener extends Plugin implements SensorEventListener {
|
|||||||
this.setStatus(AccelListener.STOPPED);
|
this.setStatus(AccelListener.STOPPED);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the context of the Command. This can then be used to do things like
|
* Sets the context of the Command. This can then be used to do things like
|
||||||
* get file paths associated with the Activity.
|
* get file paths associated with the Activity.
|
||||||
*
|
*
|
||||||
* @param ctx The context of the main Activity.
|
* @param ctx The context of the main Activity.
|
||||||
*/
|
*/
|
||||||
public void setContext(CordovaInterface ctx) {
|
public void setContext(CordovaInterface ctx) {
|
||||||
super.setContext(ctx);
|
super.setContext(ctx);
|
||||||
this.sensorManager = (SensorManager) ctx.getSystemService(Context.SENSOR_SERVICE);
|
this.sensorManager = (SensorManager) ctx.getSystemService(Context.SENSOR_SERVICE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes the request and returns PluginResult.
|
* Executes the request and returns PluginResult.
|
||||||
*
|
*
|
||||||
* @param action The action to execute.
|
* @param action The action to execute.
|
||||||
* @param args JSONArry of arguments for the plugin.
|
* @param args JSONArry of arguments for the plugin.
|
||||||
* @param callbackId The callback id used when calling back into JavaScript.
|
* @param callbackId The callback id used when calling back into JavaScript.
|
||||||
* @return A PluginResult object with a status and message.
|
* @return A PluginResult object with a status and message.
|
||||||
*/
|
*/
|
||||||
public PluginResult execute(String action, JSONArray args, String callbackId) {
|
public PluginResult execute(String action, JSONArray args, String callbackId) {
|
||||||
PluginResult.Status status = PluginResult.Status.OK;
|
PluginResult.Status status = PluginResult.Status.NO_RESULT;
|
||||||
String result = "";
|
String message = "";
|
||||||
|
PluginResult result = new PluginResult(status, message);
|
||||||
|
result.setKeepCallback(true);
|
||||||
|
try {
|
||||||
|
if (action.equals("getAcceleration")) {
|
||||||
|
if (this.status != AccelListener.RUNNING) {
|
||||||
|
// If not running, then this is an async call, so don't worry about waiting
|
||||||
|
// We drop the callback onto our stack, call start, and let start and the sensor callback fire off the callback down the road
|
||||||
|
this.callbacks.add(callbackId);
|
||||||
|
this.start();
|
||||||
|
} else {
|
||||||
|
return new PluginResult(PluginResult.Status.OK, this.getAccelerationJSON());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (action.equals("addWatch")) {
|
||||||
|
String watchId = args.getString(0);
|
||||||
|
this.watches.put(watchId, callbackId);
|
||||||
|
if (this.status != AccelListener.RUNNING) {
|
||||||
|
this.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (action.equals("clearWatch")) {
|
||||||
|
String watchId = args.getString(0);
|
||||||
|
if (this.watches.containsKey(watchId)) {
|
||||||
|
this.watches.remove(watchId);
|
||||||
|
if (this.size() == 0) {
|
||||||
|
this.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new PluginResult(PluginResult.Status.OK);
|
||||||
|
} else {
|
||||||
|
// Unsupported action
|
||||||
|
return new PluginResult(PluginResult.Status.INVALID_ACTION);
|
||||||
|
}
|
||||||
|
} catch (JSONException e) {
|
||||||
|
return new PluginResult(PluginResult.Status.JSON_EXCEPTION);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
/**
|
||||||
if (action.equals("getStatus")) {
|
* Identifies if action to be executed returns a value and should be run synchronously.
|
||||||
int i = this.getStatus();
|
*
|
||||||
return new PluginResult(status, i);
|
* @param action The action to execute
|
||||||
}
|
* @return T=returns value
|
||||||
else if (action.equals("start")) {
|
*/
|
||||||
int i = this.start();
|
public boolean isSynch(String action) {
|
||||||
return new PluginResult(status, i);
|
if (action.equals("getAcceleration") && this.status == AccelListener.RUNNING) {
|
||||||
}
|
return true;
|
||||||
else if (action.equals("stop")) {
|
} else if (action.equals("addWatch") && this.status == AccelListener.RUNNING) {
|
||||||
this.stop();
|
return true;
|
||||||
return new PluginResult(status, 0);
|
} else if (action.equals("clearWatch")) {
|
||||||
}
|
return true;
|
||||||
else if (action.equals("getAcceleration")) {
|
}
|
||||||
// If not running, then this is an async call, so don't worry about waiting
|
return false;
|
||||||
if (this.status != AccelListener.RUNNING) {
|
}
|
||||||
int r = this.start();
|
|
||||||
if (r == AccelListener.ERROR_FAILED_TO_START) {
|
|
||||||
return new PluginResult(PluginResult.Status.IO_EXCEPTION, AccelListener.ERROR_FAILED_TO_START);
|
|
||||||
}
|
|
||||||
// Wait until running
|
|
||||||
long timeout = 2000;
|
|
||||||
while ((this.status == STARTING) && (timeout > 0)) {
|
|
||||||
timeout = timeout - 100;
|
|
||||||
try {
|
|
||||||
Thread.sleep(100);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (timeout == 0) {
|
|
||||||
return new PluginResult(PluginResult.Status.IO_EXCEPTION, AccelListener.ERROR_FAILED_TO_START);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.lastAccessTime = System.currentTimeMillis();
|
|
||||||
JSONObject r = new JSONObject();
|
|
||||||
r.put("x", this.x);
|
|
||||||
r.put("y", this.y);
|
|
||||||
r.put("z", this.z);
|
|
||||||
// TODO: Should timestamp be sent?
|
|
||||||
r.put("timestamp", this.timestamp);
|
|
||||||
return new PluginResult(status, r);
|
|
||||||
}
|
|
||||||
else if (action.equals("setTimeout")) {
|
|
||||||
try {
|
|
||||||
float timeout = Float.parseFloat(args.getString(0));
|
|
||||||
this.setTimeout(timeout);
|
|
||||||
return new PluginResult(status, 0);
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
status = PluginResult.Status.INVALID_ACTION;
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (JSONException e) {
|
|
||||||
status = PluginResult.Status.JSON_EXCEPTION;
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (action.equals("getTimeout")) {
|
|
||||||
float f = this.getTimeout();
|
|
||||||
return new PluginResult(status, f);
|
|
||||||
} else {
|
|
||||||
// Unsupported action
|
|
||||||
return new PluginResult(PluginResult.Status.INVALID_ACTION);
|
|
||||||
}
|
|
||||||
return new PluginResult(status, result);
|
|
||||||
} catch (JSONException e) {
|
|
||||||
return new PluginResult(PluginResult.Status.JSON_EXCEPTION);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Identifies if action to be executed returns a value and should be run synchronously.
|
|
||||||
*
|
|
||||||
* @param action The action to execute
|
|
||||||
* @return T=returns value
|
|
||||||
*/
|
|
||||||
public boolean isSynch(String action) {
|
|
||||||
if (action.equals("getStatus")) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (action.equals("getAcceleration")) {
|
|
||||||
// Can only return value if RUNNING
|
|
||||||
if (this.status == AccelListener.RUNNING) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (action.equals("getTimeout")) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called by AccelBroker when listener is to be shut down.
|
* Called by AccelBroker when listener is to be shut down.
|
||||||
* Stop listener.
|
* Stop listener.
|
||||||
*/
|
*/
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
this.stop();
|
this.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
// LOCAL METHODS
|
// LOCAL METHODS
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
private int size() {
|
||||||
|
return this.watches.size() + this.callbacks.size();
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Start listening for acceleration sensor.
|
* Start listening for acceleration sensor.
|
||||||
*
|
*
|
||||||
* @return status of listener
|
* @return status of listener
|
||||||
*/
|
*/
|
||||||
public int start() {
|
private int start() {
|
||||||
|
// If already starting or running, then just return
|
||||||
|
if ((this.status == AccelListener.RUNNING) || (this.status == AccelListener.STARTING)) {
|
||||||
|
return this.status;
|
||||||
|
}
|
||||||
|
|
||||||
// If already starting or running, then just return
|
this.setStatus(AccelListener.STARTING);
|
||||||
if ((this.status == AccelListener.RUNNING) || (this.status == AccelListener.STARTING)) {
|
|
||||||
return this.status;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get accelerometer from sensor manager
|
// Get accelerometer from sensor manager
|
||||||
List<Sensor> list = this.sensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER);
|
List<Sensor> list = this.sensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER);
|
||||||
|
|
||||||
// If found, then register as listener
|
// If found, then register as listener
|
||||||
if ((list != null) && (list.size() > 0)) {
|
if ((list != null) && (list.size() > 0)) {
|
||||||
this.mSensor = list.get(0);
|
this.mSensor = list.get(0);
|
||||||
this.sensorManager.registerListener(this, this.mSensor, SensorManager.SENSOR_DELAY_FASTEST);
|
this.sensorManager.registerListener(this, this.mSensor, SensorManager.SENSOR_DELAY_FASTEST);
|
||||||
this.setStatus(AccelListener.STARTING);
|
this.setStatus(AccelListener.STARTING);
|
||||||
this.lastAccessTime = System.currentTimeMillis();
|
} else {
|
||||||
}
|
this.setStatus(AccelListener.ERROR_FAILED_TO_START);
|
||||||
|
this.fail(AccelListener.ERROR_FAILED_TO_START, "No sensors found to register accelerometer listening to.");
|
||||||
|
return this.status;
|
||||||
|
}
|
||||||
|
|
||||||
// If error, then set status to error
|
// Wait until running
|
||||||
else {
|
long timeout = 2000;
|
||||||
this.setStatus(AccelListener.ERROR_FAILED_TO_START);
|
while ((this.status == STARTING) && (timeout > 0)) {
|
||||||
}
|
timeout = timeout - 100;
|
||||||
|
try {
|
||||||
return this.status;
|
Thread.sleep(100);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (timeout == 0) {
|
||||||
|
this.setStatus(AccelListener.ERROR_FAILED_TO_START);
|
||||||
|
this.fail(AccelListener.ERROR_FAILED_TO_START, "Accelerometer could not be started.");
|
||||||
|
}
|
||||||
|
return this.status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop listening to acceleration sensor.
|
* Stop listening to acceleration sensor.
|
||||||
*/
|
*/
|
||||||
public void stop() {
|
private void stop() {
|
||||||
if (this.status != AccelListener.STOPPED) {
|
if (this.status != AccelListener.STOPPED) {
|
||||||
this.sensorManager.unregisterListener(this);
|
this.sensorManager.unregisterListener(this);
|
||||||
}
|
}
|
||||||
this.setStatus(AccelListener.STOPPED);
|
this.setStatus(AccelListener.STOPPED);
|
||||||
}
|
}
|
||||||
@ -248,64 +234,92 @@ public class AccelListener extends Plugin implements SensorEventListener {
|
|||||||
* @param SensorEvent event
|
* @param SensorEvent event
|
||||||
*/
|
*/
|
||||||
public void onSensorChanged(SensorEvent event) {
|
public void onSensorChanged(SensorEvent event) {
|
||||||
|
// Only look at accelerometer events
|
||||||
// Only look at accelerometer events
|
|
||||||
if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER) {
|
if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If not running, then just return
|
// If not running, then just return
|
||||||
if (this.status == AccelListener.STOPPED) {
|
if (this.status == AccelListener.STOPPED) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.setStatus(AccelListener.RUNNING);
|
||||||
|
|
||||||
// Save time that event was received
|
// Save time that event was received
|
||||||
this.timestamp = System.currentTimeMillis();
|
this.timestamp = System.currentTimeMillis();
|
||||||
this.x = event.values[0];
|
this.x = event.values[0];
|
||||||
this.y = event.values[1];
|
this.y = event.values[1];
|
||||||
this.z = event.values[2];
|
this.z = event.values[2];
|
||||||
|
|
||||||
this.setStatus(AccelListener.RUNNING);
|
this.win();
|
||||||
|
|
||||||
// If values haven't been read for TIMEOUT time, then turn off accelerometer sensor to save power
|
if (this.size() == 0) {
|
||||||
if ((this.timestamp - this.lastAccessTime) > this.TIMEOUT) {
|
this.stop();
|
||||||
this.stop();
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private void fail(int code, String message) {
|
||||||
* Get status of accelerometer sensor.
|
// Error object
|
||||||
*
|
JSONObject errorObj = new JSONObject();
|
||||||
* @return status
|
try {
|
||||||
*/
|
errorObj.put("code", code);
|
||||||
public int getStatus() {
|
errorObj.put("message", message);
|
||||||
return this.status;
|
} catch (JSONException e) {
|
||||||
}
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
PluginResult err = new PluginResult(PluginResult.Status.ERROR, errorObj);
|
||||||
|
|
||||||
/**
|
for (String callbackId: this.callbacks)
|
||||||
* Set the timeout to turn off accelerometer sensor if getX() hasn't been called.
|
{
|
||||||
*
|
this.error(err, callbackId);
|
||||||
* @param timeout Timeout in msec.
|
}
|
||||||
*/
|
this.callbacks.clear();
|
||||||
public void setTimeout(float timeout) {
|
|
||||||
this.TIMEOUT = timeout;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
err.setKeepCallback(true);
|
||||||
* Get the timeout to turn off accelerometer sensor if getX() hasn't been called.
|
|
||||||
*
|
Iterator it = this.watches.entrySet().iterator();
|
||||||
* @return timeout in msec
|
while (it.hasNext()) {
|
||||||
*/
|
Map.Entry pairs = (Map.Entry)it.next();
|
||||||
public float getTimeout() {
|
this.error(err, (String)pairs.getValue());
|
||||||
return this.TIMEOUT;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void win() {
|
||||||
|
// Success return object
|
||||||
|
PluginResult result = new PluginResult(PluginResult.Status.OK, this.getAccelerationJSON());
|
||||||
|
|
||||||
|
for (String callbackId: this.callbacks)
|
||||||
|
{
|
||||||
|
this.success(result, callbackId);
|
||||||
|
}
|
||||||
|
this.callbacks.clear();
|
||||||
|
|
||||||
|
result.setKeepCallback(true);
|
||||||
|
|
||||||
|
Iterator it = this.watches.entrySet().iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
Map.Entry pairs = (Map.Entry)it.next();
|
||||||
|
this.success(result, (String)pairs.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the status and send it to JavaScript.
|
|
||||||
* @param status
|
|
||||||
*/
|
|
||||||
private void setStatus(int status) {
|
private void setStatus(int status) {
|
||||||
this.status = status;
|
this.status = status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private JSONObject getAccelerationJSON() {
|
||||||
|
JSONObject r = new JSONObject();
|
||||||
|
try {
|
||||||
|
r.put("x", this.x);
|
||||||
|
r.put("y", this.y);
|
||||||
|
r.put("z", this.z);
|
||||||
|
r.put("timestamp", this.timestamp);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user