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.
Most Android-powered devices have an accelerometer, and many now include a gyroscope.
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.
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.
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 }
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();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With