Java tutorial
/* This file was modified from or inspired by Apache Cordova. 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 com.polyvi.xface.extension; import java.util.List; 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 com.polyvi.xface.extension.XExtensionResult.Status; public class XAccelerometerExt extends XExtension implements SensorEventListener { private final static int STOPPED = 0; private final static int STARTING = 1; private final static int RUNNING = 2; private final static int ERROR_FAILED_TO_START = 3; private final static String COMMAND_START = "start"; private final static String COMMAND_STOP = "stop"; private float mX, mY, mZ; // acceleration private long mTimestamp; // acceleration private int mStatus; // ?? private int mAccuracy; // ?? private SensorManager mSensorManager; // Acceleration sensor private Sensor mSensor; // Acceleration sensor private XCallbackContext mCallbackCtx; public XAccelerometerExt() { mX = 0; mY = 0; mZ = 0; mTimestamp = 0; mStatus = STOPPED; mAccuracy = SensorManager.SENSOR_STATUS_UNRELIABLE; } @Override public void sendAsyncResult(String result) { } @Override public boolean isAsync(String action) { return action.equals(COMMAND_START) && mStatus != RUNNING; } @Override public XExtensionResult exec(String action, JSONArray args, XCallbackContext callbackCtx) { XExtensionResult.Status extensionStatus = Status.NO_RESULT; mCallbackCtx = callbackCtx; if (action.equals(COMMAND_START)) { if (mStatus != RUNNING) { start(); } } else if (action.equals(COMMAND_STOP)) { if (RUNNING == mStatus) { stop(); } extensionStatus = Status.OK; } else { extensionStatus = Status.INVALID_ACTION; } return new XExtensionResult(extensionStatus); } /** * ?accelerometer sensor */ private void start() { if ((mStatus == RUNNING) || (mStatus == STARTING)) { return; } mStatus = STARTING; if (null == mSensorManager) { mSensorManager = (SensorManager) getContext().getSystemService(Context.SENSOR_SERVICE); } List<Sensor> list = mSensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER); if ((list != null) && (list.size() > 0)) { mSensor = list.get(0); mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_UI); } else { mStatus = ERROR_FAILED_TO_START; mCallbackCtx.error("No sensors found to register accelerometer listening to."); } // Wait until running long timeout = 2000; while ((this.mStatus == STARTING) && (timeout > 0)) { timeout = timeout - 100; try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } if (timeout == 0) { mStatus = ERROR_FAILED_TO_START; mCallbackCtx.error("Accelerometer could not be started."); } } /** * ??accelerometer sensor */ private void stop() { if (STOPPED != mStatus && null != mSensorManager) { mSensorManager.unregisterListener(this); } mStatus = STOPPED; mAccuracy = SensorManager.SENSOR_STATUS_UNRELIABLE; } private void win() { XExtensionResult result = new XExtensionResult(Status.OK, getAccelerationJSON()); result.setKeepCallback(true); mCallbackCtx.sendExtensionResult(result); } /** * ?json??? */ private JSONObject getAccelerationJSON() { JSONObject r = new JSONObject(); try { r.put("x", mX); r.put("y", mY); r.put("z", mZ); r.put("timestamp", mTimestamp); } catch (JSONException e) { e.printStackTrace(); } return r; } @Override 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 (mStatus == STOPPED) { return; } mAccuracy = accuracy; } @Override 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 (mStatus == STOPPED) { return; } mStatus = RUNNING; if (mAccuracy >= SensorManager.SENSOR_STATUS_ACCURACY_MEDIUM) { mTimestamp = System.currentTimeMillis(); mX = event.values[0]; mY = event.values[1]; mZ = event.values[2]; win(); } } @Override public void destroy() { stop(); super.destroy(); } }