Как обнаружить движение устройства Android?

Мне нужно знать, как определить количество движений устройства Android. Предположим, я положил телефон на стол или кровать, а затем, если кто-то постучит по столу или сидит или укладывается на кровать, я хочу обнаружить движение устройства Android.

На самом деле я знаю, что у андроида есть API-интерфейсы датчиков движения, но я не знаю, какой датчик использовать и какой тип датчика лучше всего подходит для обнаружения такого типа.

Я был бы рад, если кто-то может поделиться базовым демо-кодом.

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 имеет встроенный конвертер, чтобы найти ЛИНЕЙНОЕ УСКОРЕНИЕ, действующее на вашем мобильном телефоне

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

Это код, в котором вы можете увидеть, как получить исходное значение ЛИНЕЙНОГО УСКОРЕНИЯ