如何检测Android设备的移动?

我需要关于如何检测Android设备的移动量的build议。 假设我把手机放在桌子或床上,然后如果有人点击桌子或坐在床上或躺在床上,那么我想检测Android设备的移动。

其实我知道android有运动传感器API,但我不知道要使用哪种传感器,以及哪种传感器types最适合这种types的运动检测。

如果有人能分享一些基本的演示代码,我会很高兴。

Solutions Collecting From Web of "如何检测Android设备的移动?"

绝对与加速度计一起工作:

// Start with some variables private SensorManager sensorMan; private Sensor accelerometer; private float[] mGravity; private float mAccel; private float mAccelCurrent; private float mAccelLast; // In onCreate method sensorMan = (SensorManager)getSystemService(SENSOR_SERVICE); accelerometer = sensorMan.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); mAccel = 0.00f; mAccelCurrent = SensorManager.GRAVITY_EARTH; mAccelLast = SensorManager.GRAVITY_EARTH; // And these: @Override public void onResume() { super.onResume(); sensorMan.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_UI); } @Override protected void onPause() { super.onPause(); sensorMan.unregisterListener(this); } @Override public void onSensorChanged(SensorEvent event) { if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER){ mGravity = event.values.clone(); // Shake detection float x = mGravity[0]; float y = mGravity[1]; float z = mGravity[2]; mAccelLast = mAccelCurrent; mAccelCurrent = FloatMath.sqrt(x*x + y*y + z*z); float delta = mAccelCurrent - mAccelLast; mAccel = mAccel * 0.9f + delta; // Make this higher or lower according to how much // motion you want to detect if(mAccel > 3){ // do something } } } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { // required method } 

我使用了以下类:

 public class MovementDetector implements SensorEventListener { protected final String TAG = getClass().getSimpleName(); private SensorManager sensorMan; private Sensor accelerometer; private MovementDetector() { } private static MovementDetector mInstance; public static MovementDetector getInstance() { if (mInstance == null) { mInstance = new MovementDetector(); mInstance.init(); } return mInstance; } ////////////////////// private HashSet<Listener> mListeners = new HashSet<MovementDetector.Listener>(); private void init() { sensorMan = (SensorManager) GlobalData.getInstance().getContext().getSystemService(Context.SENSOR_SERVICE); accelerometer = sensorMan.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION); } public void start() { sensorMan.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL); } public void stop() { sensorMan.unregisterListener(this); } public void addListener(Listener listener) { mListeners.add(listener); } /* (non-Javadoc) * @see android.hardware.SensorEventListener#onSensorChanged(android.hardware.SensorEvent) */ @Override public void onSensorChanged(SensorEvent event) { if (event.sensor.getType() == Sensor.TYPE_LINEAR_ACCELERATION) { float x = event.values[0]; float y = event.values[1]; float z = event.values[2]; float diff = (float) Math.sqrt(x * x + y * y + z * z); if (diff > 0.5) // 0.5 is a threshold, you can test it and change it Log.d(TAG,"Device motion detected!!!!"); for (Listener listener : mListeners) { listener.onMotionDetected(event, diff); } } } /* (non-Javadoc) * @see android.hardware.SensorEventListener#onAccuracyChanged(android.hardware.Sensor, int) */ @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { // TODO Auto-generated method stub } public interface Listener { void onMotionDetected(SensorEvent event, float acceleration); } } 

用法:

在我的活动onCrate()

  MovementDetector.getInstance().addListener(new MovementDetector.Listener() { @Override public void onMotionDetected(SensorEvent event, float acceleration) { mMotionDetectionTextView.setText("Acceleration: ["+String.format("%.3f",event.values[0])+","+String.format("%.3f",event.values[1])+","+String.format("%.3f",event.values[2])+"] "+String.format("%.3f", acceleration)); if (acceleration > SettingsHelper.getInstance().getMotionDetectionThreshold()){ mMotionDetectionTextView.setTextColor(Color.RED); } else { mMotionDetectionTextView.setTextColor(Color.WHITE); } } }); 

在我的活动onResume()

 MovementDetector.getInstance().start(); 

在我的活动onPause()

 MovementDetector.getInstance().stop(); 

此代码用于步行检测(由@anthropomo代码修改)

获得更平滑的价值。

//初始化

 private SensorManager sensorMan; private Sensor accelerometer; private float[] mGravity; private double mAccel; private double mAccelCurrent; private double mAccelLast; private boolean sensorRegistered = false; 

// onCreate

  sensorMan = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); accelerometer = sensorMan.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); mAccel = 0.00f; mAccelCurrent = SensorManager.GRAVITY_EARTH; mAccelLast = SensorManager.GRAVITY_EARTH; sensorMan.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL); sensorRegistered = true; 

// onSensorChanged

 private int hitCount = 0; private double hitSum = 0; private double hitResult = 0; private final int SAMPLE_SIZE = 50; // change this sample size as you want, higher is more precise but slow measure. private final double THRESHOLD = 0.2; // change this threshold as you want, higher is more spike movement @Override public void onSensorChanged(SensorEvent event) { if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { mGravity = event.values.clone(); // Shake detection double x = mGravity[0]; double y = mGravity[1]; double z = mGravity[2]; mAccelLast = mAccelCurrent; mAccelCurrent = Math.sqrt(x * x + y * y + z * z); double delta = mAccelCurrent - mAccelLast; mAccel = mAccel * 0.9f + delta; if (hitCount <= SAMPLE_SIZE) { hitCount++; hitSum += Math.abs(mAccel); } else { hitResult = hitSum / SAMPLE_SIZE; Log.d(TAG, String.valueOf(hitResult)); if (hitResult > THRESHOLD) { Log.d(TAG, "Walking"); } else { Log.d(TAG, "Stop Walking"); } hitCount = 0; hitSum = 0; hitResult = 0; } } } 

虽然我没有演示代码(因为你不够具体),一个好的开始在这里: http : //developer.android.com/guide/topics/sensors/sensors_motion.html (和左边的其他项目)。

如果您正在尝试查找手机的位移,则需要查找作用于手机的线性加速度,而不是重力加速度

android有一个内置的转换器,以find您的手机上的直线加速

https://github.com/yuvaramsingh94/AndroidSensorTestCode/tree/master

这是一个代码,您可以看到如何获得LINEAR ACCELERATION的原始值