You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by st...@apache.org on 2013/03/25 21:24:16 UTC

[2/2] git commit: updated device motion plugin

updated device motion plugin


Project: http://git-wip-us.apache.org/repos/asf/cordova-plugin-device-motion/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-plugin-device-motion/commit/8866337a
Tree: http://git-wip-us.apache.org/repos/asf/cordova-plugin-device-motion/tree/8866337a
Diff: http://git-wip-us.apache.org/repos/asf/cordova-plugin-device-motion/diff/8866337a

Branch: refs/heads/master
Commit: 8866337a30a833fb2d6c91e0b10cbbac7a1e41f0
Parents: ab75846
Author: Steven Gill <st...@gmail.com>
Authored: Wed Mar 20 16:22:21 2013 -0700
Committer: Steven Gill <st...@gmail.com>
Committed: Wed Mar 20 16:22:21 2013 -0700

----------------------------------------------------------------------
 plugin.xml                     |   17 ++
 src/android/AccelListener.java |  286 +++++++++++++++++++++++++++++++++++
 2 files changed, 303 insertions(+), 0 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-plugin-device-motion/blob/8866337a/plugin.xml
----------------------------------------------------------------------
diff --git a/plugin.xml b/plugin.xml
new file mode 100644
index 0000000..35b186a
--- /dev/null
+++ b/plugin.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<plugin xmlns="http://www.phonegap.com/ns/plugins/1.0"
+xmlns:android="http://schemas.android.com/apk/res/android"
+id="org.apache.cordova.core">
+    version="0.1.0">
+	<name>Device Motion</name>
+
+	<!-- android -->
+	<platform name="android">
+		<config-file target="res/xml/config.xml" parent="/cordova/plugins">
+			<plugin name="Accelerometer" value="org.apache.cordova.core.AccelListener"/>
+		</config-file>
+
+		<source-file src="AccelListener.java" target-dir="org/apache/cordova/core" />
+       </platform>
+</plugin>

http://git-wip-us.apache.org/repos/asf/cordova-plugin-device-motion/blob/8866337a/src/android/AccelListener.java
----------------------------------------------------------------------
diff --git a/src/android/AccelListener.java b/src/android/AccelListener.java
new file mode 100755
index 0000000..1c43770
--- /dev/null
+++ b/src/android/AccelListener.java
@@ -0,0 +1,286 @@
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+package org.apache.cordova.core;
+
+import java.util.List;
+
+import org.apache.cordova.CordovaWebView;
+import org.apache.cordova.api.CallbackContext;
+import org.apache.cordova.api.CordovaInterface;
+import org.apache.cordova.api.CordovaPlugin;
+import org.apache.cordova.api.PluginResult;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import android.content.Context;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+
+import android.os.Handler;
+import android.os.Looper;
+
+/**
+ * This class listens to the accelerometer sensor and stores the latest
+ * acceleration values x,y,z.
+ */
+public class AccelListener extends CordovaPlugin implements SensorEventListener {
+
+    public static int STOPPED = 0;
+    public static int STARTING = 1;
+    public static int RUNNING = 2;
+    public static int ERROR_FAILED_TO_START = 3;
+   
+    private float x,y,z;                                // most recent acceleration values
+    private long timestamp;                         // time of most recent value
+    private int status;                                 // status of listener
+    private int accuracy = SensorManager.SENSOR_STATUS_UNRELIABLE;
+
+    private SensorManager sensorManager;    // Sensor manager
+    private Sensor mSensor;                           // Acceleration sensor returned by sensor manager
+
+    private CallbackContext callbackContext;              // Keeps track of the JS callback context.
+
+    /**
+     * Create an accelerometer listener.
+     */
+    public AccelListener() {
+        this.x = 0;
+        this.y = 0;
+        this.z = 0;
+        this.timestamp = 0;
+        this.setStatus(AccelListener.STOPPED);
+     }
+
+    /**
+     * Sets the context of the Command. This can then be used to do things like
+     * get file paths associated with the Activity.
+     *
+     * @param cordova The context of the main Activity.
+     * @param webView The associated CordovaWebView.
+     */
+    @Override
+    public void initialize(CordovaInterface cordova, CordovaWebView webView) {
+        super.initialize(cordova, webView);
+        this.sensorManager = (SensorManager) cordova.getActivity().getSystemService(Context.SENSOR_SERVICE);
+    }
+
+    /**
+     * Executes the request.
+     *
+     * @param action        The action to execute.
+     * @param args          The exec() arguments.
+     * @param callbackId    The callback id used when calling back into JavaScript.
+     * @return              Whether the action was valid.
+     */
+    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) {
+        if (action.equals("start")) {
+            this.callbackContext = callbackContext;
+            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.start();
+            }
+        }
+        else if (action.equals("stop")) {
+            if (this.status == AccelListener.RUNNING) {
+                this.stop();
+            }
+        } else {
+          // Unsupported action
+            return false;
+        }
+
+        PluginResult result = new PluginResult(PluginResult.Status.NO_RESULT, "");
+        result.setKeepCallback(true);
+        callbackContext.sendPluginResult(result);
+        return true;
+    }
+
+    /**
+     * Called by AccelBroker when listener is to be shut down.
+     * Stop listener.
+     */
+    public void onDestroy() {
+        this.stop();
+    }
+
+    //--------------------------------------------------------------------------
+    // LOCAL METHODS
+    //--------------------------------------------------------------------------
+    //
+    /**
+     * Start listening for acceleration sensor.
+     * 
+     * @return          status of listener
+    */
+    private int start() {
+        // If already starting or running, then just return
+        if ((this.status == AccelListener.RUNNING) || (this.status == AccelListener.STARTING)) {
+            return this.status;
+        }
+
+        this.setStatus(AccelListener.STARTING);
+
+        // Get accelerometer from sensor manager
+        List<Sensor> list = this.sensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER);
+
+        // If found, then register as listener
+        if ((list != null) && (list.size() > 0)) {
+          this.mSensor = list.get(0);
+          this.sensorManager.registerListener(this, this.mSensor, SensorManager.SENSOR_DELAY_UI);
+          this.setStatus(AccelListener.STARTING);
+        } 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;
+        }
+
+        // Set a timeout callback on the main thread.
+        Handler handler = new Handler(Looper.getMainLooper());
+        handler.postDelayed(new Runnable() {
+            public void run() {
+                AccelListener.this.timeout();
+            }
+        }, 2000);
+
+        return this.status;
+    }
+
+    /**
+     * Stop listening to acceleration sensor.
+     */
+    private void stop() {
+        if (this.status != AccelListener.STOPPED) {
+            this.sensorManager.unregisterListener(this);
+        }
+        this.setStatus(AccelListener.STOPPED);
+        this.accuracy = SensorManager.SENSOR_STATUS_UNRELIABLE;
+    }
+
+    /**
+     * Returns an error if the sensor hasn't started.
+     *
+     * Called two seconds after starting the listener.
+     */
+    private void timeout() {
+        if (this.status == AccelListener.STARTING) {
+            this.setStatus(AccelListener.ERROR_FAILED_TO_START);
+            this.fail(AccelListener.ERROR_FAILED_TO_START, "Accelerometer could not be started.");
+        }
+    }
+
+    /**
+     * Called when the accuracy of the sensor has changed.
+     *
+     * @param sensor
+     * @param accuracy
+     */
+    public void onAccuracyChanged(Sensor sensor, int accuracy) {
+        // Only look at accelerometer events
+        if (sensor.getType() != Sensor.TYPE_ACCELEROMETER) {
+            return;
+        }
+
+        // If not running, then just return
+        if (this.status == AccelListener.STOPPED) {
+            return;
+        }
+        this.accuracy = accuracy;
+    }
+
+    /**
+     * Sensor listener event.
+     *
+     * @param SensorEvent event
+     */
+    public void onSensorChanged(SensorEvent event) {
+        // Only look at accelerometer events
+        if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER) {
+            return;
+        }
+
+        // If not running, then just return
+        if (this.status == AccelListener.STOPPED) {
+            return;
+        }
+        this.setStatus(AccelListener.RUNNING);
+
+        if (this.accuracy >= SensorManager.SENSOR_STATUS_ACCURACY_MEDIUM) {
+
+            // Save time that event was received
+            this.timestamp = System.currentTimeMillis();
+            this.x = event.values[0];
+            this.y = event.values[1];
+            this.z = event.values[2];
+
+            this.win();
+        }
+    }
+
+    /**
+     * Called when the view navigates.
+     */
+    @Override
+    public void onReset() {
+        if (this.status == AccelListener.RUNNING) {
+            this.stop();
+        }
+    }
+
+    // Sends an error back to JS
+    private void fail(int code, String message) {
+        // Error object
+        JSONObject errorObj = new JSONObject();
+        try {
+            errorObj.put("code", code);
+            errorObj.put("message", message);
+        } catch (JSONException e) {
+            e.printStackTrace();
+        }
+        PluginResult err = new PluginResult(PluginResult.Status.ERROR, errorObj);
+        err.setKeepCallback(true);
+        callbackContext.sendPluginResult(err);
+    }
+
+    private void win() {
+        // Success return object
+        PluginResult result = new PluginResult(PluginResult.Status.OK, this.getAccelerationJSON());
+        result.setKeepCallback(true);
+        callbackContext.sendPluginResult(result);
+    }
+
+    private void setStatus(int 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) {
+            e.printStackTrace();
+        }
+        return r;
+    }
+}