Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect movement of an android device?

I need suggestion about how to detect the amount of movement of an android device. Suppose I have put the phone on a table or bed and then if somebody taps the table or sits or laydown on the bed then I want to detect the movement of the android device.

Actually I know that android has motion sensors APIs but I don't know which sensor to use and what sensor type is best for this type of movement detection.

I would be glad if someone can share some basic demo code.

like image 337
Surjya Narayana Padhi Avatar asked Jan 29 '13 02:01

Surjya Narayana Padhi


People also ask

What detects movement in a phone?

Most Android-powered devices have an accelerometer, and many now include a gyroscope.

How can smart device detect movement?

Motion Sensors. Three main sensors are embedded in modern smart devices for motion detection: accelerometer, gyroscope, and magnetometer. The accelerometer detects changes in the device displacement, orientation, and tilt around three axes by measuring acceleration forces.

Can accelerometer detect movement?

Movement DetectionIf a project wants to detect any movement or measure a movement, an accelerometer is perfect. If you are looking for a specific location to where something has moved, an accelerometer will not provide that data, a GPS unit would be a better sensor for exact location data.


2 Answers

Definitely work with the accelerometer:

// 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 } 
like image 157
anthropomo Avatar answered Sep 29 '22 02:09

anthropomo


I used the following class:

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);     } } 

Usage:

On my activity 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);             }          }     }); 

On my activity onResume():

MovementDetector.getInstance().start(); 

On my activity onPause():

MovementDetector.getInstance().stop(); 
like image 45
Asaf Pinhassi Avatar answered Sep 29 '22 03:09

Asaf Pinhassi