How to Integrate Android Accelerometer In Your Android App to Detect Shake Event of Device

android accelerometer

Android Accelerometer. What is Android Accelerometer?

We barely notice it, but it is one of the most important feature buried in the everyday smartphone experience.

Before the arrival of smartphones, the keyboard was one of the few hardware components was used for interaction. Now, the times have changed and interacting with hardware has become more common.

Today, gestures feel more natural than interacting with a hardware, especially for touch devices such as tablets and smartphones.

These gestures bring an android app to life by making it more exciting and interesting for the users. And, to implement such gestures in an android app, Android Accelerometer is used.

How Android Accelerometer Work?

Android accelerometer usually measures the acceleration by force.

How?

In simple words, Android Accelerometer senses how much a mass presses on something when a force acts on it.

This is something that almost everyone is familiar with. So, let’s go ahead and see how you can integrate Android accelerometer in your Android app to detect shake in an Android device.

Let’s Get Started

Create a new project “Shake Motion Detection”.

Android Accelerometer

Select the target Android device.

Android Accelerometer

Add an activity to mobile -> Select Empty Activity.

Android Accelerometer

Customize the Activity.

Android Accelerometer

Create Java interface name “AccelerometerListener”

package com.spaceo.shakedetectiondemo;

public interface AccelerometerListener {

public void onAccelerationChanged(float x, float y, float z);

public void onShake(float force);
}

Create Java class name “AccelerometerManager”

package com.spaceo.shakedetectiondemo;

import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.widget.Toast;

import java.util.List;
public class AccelerometerManager {

private static Context context = null;
/**
* Accuracy configuration
*/
private static float threshold = 15.0f;
private static int interval = 200;

private static Sensor sensor;
private static SensorManager sensorManager;
// you could use an OrientationListener array instead
// if you plans to use more than one listener
private static AccelerometerListener listener;

/**
* indicates whether or not Accelerometer Sensor is supported
*/
private static Boolean supported;
/**
* indicates whether or not Accelerometer Sensor is running
*/
private static boolean running = false;

/**
* Returns true if the manager is listening to orientation changes
*/
public static boolean isListening() {
return running;
}

/**
* Unregisters listeners
*/
public static void stopListening() {
running = false;
try {
if (sensorManager != null && sensorEventListener != null) {
sensorManager.unregisterListener(sensorEventListener);
}
} catch (Exception e) {
}
}

/**
* Returns true if at least one Accelerometer sensor is available
*/
public static boolean isSupported(Context cntxt) {
context = cntxt;
if (supported == null) {
if (context != null) {

sensorManager = (SensorManager) context.
getSystemService(Context.SENSOR_SERVICE);

// Get all sensors in device
List<Sensor> sensors = sensorManager.getSensorList(
Sensor.TYPE_ACCELEROMETER);

supported = new Boolean(sensors.size() > 0);
} else {
supported = Boolean.FALSE;
}
}
return supported;
}

/**
* Configure the listener for shaking
*
* @param threshold minimum acceleration variation for considering shaking
* @param interval minimum interval between to shake events
*/
public static void configure(int threshold, int interval) {
AccelerometerManager.threshold = threshold;
AccelerometerManager.interval = interval;
}

/**
* Registers a listener and start listening
*
* @param accelerometerListener callback for accelerometer events
*/
public static void startListening(AccelerometerListener accelerometerListener) {

sensorManager = (SensorManager) context.
getSystemService(Context.SENSOR_SERVICE);

// Take all sensors in device
List<Sensor> sensors = sensorManager.getSensorList(
Sensor.TYPE_ACCELEROMETER);

if (sensors.size() > 0) {

sensor = sensors.get(0);

// Register Accelerometer Listener
running = sensorManager.registerListener(
sensorEventListener, sensor,
SensorManager.SENSOR_DELAY_GAME);

listener = accelerometerListener;
}
}

/**
* Configures threshold and interval
* And registers a listener and start listening
*
* @param accelerometerListener callback for accelerometer events
* @param threshold minimum acceleration variation for considering shaking
* @param interval minimum interval between to shake events
*/
public static void startListening(AccelerometerListener accelerometerListener, int threshold, int interval) {
configure(threshold, interval);
startListening(accelerometerListener);
}

private static SensorEventListener sensorEventListener = new SensorEventListener() {

private long now = 0;
private long timeDiff = 0;
private long lastUpdate = 0;
private long lastShake = 0;

private float x = 0;
private float y = 0;
private float z = 0;
private float lastX = 0;
private float lastY = 0;
private float lastZ = 0;
private float force = 0;

public void onAccuracyChanged(Sensor sensor, int accuracy) {
}

public void onSensorChanged(SensorEvent event) {
// use the event timestamp as reference
// so the manager precision won't depends
// on the AccelerometerListener implementation
// processing time
now = event.timestamp;

x = event.values[0];
y = event.values[1];
z = event.values[2];

// if not interesting in shake events
// just remove the whole if then else block
if (lastUpdate == 0) {
lastUpdate = now;
lastShake = now;
lastX = x;
lastY = y;
lastZ = z;
Toast.makeText(context, "No Motion detected", Toast.LENGTH_SHORT).show();

} else {
timeDiff = now - lastUpdate;

if (timeDiff > 0) {

force = Math.abs(x + y + z - lastX - lastY - lastZ);

if (Float.compare(force, threshold) > 0) {

if (now - lastShake >= interval) {
// trigger shake event
listener.onShake(force);
} else {
Toast.makeText(context, "No Motion detected",
Toast.LENGTH_SHORT).show();

}
lastShake = now;
}
lastX = x;
lastY = y;
lastZ = z;
lastUpdate = now;
} else {
Toast.makeText(context, "No Motion detected", Toast.LENGTH_SHORT).show();
}
}
// trigger change event
listener.onAccelerationChanged(x, y, z);
}
};
}

Create Java class name “MainActivity”

package com.spaceo.shakedetectiondemo;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity implements AccelerometerListener {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}

@Override
protected void onResume() {
super.onResume();
if (AccelerometerManager.isSupported(this)) {
AccelerometerManager.startListening(this);
}
}

@Override
public void onAccelerationChanged(float x, float y, float z) {

}

@Override
public void onShake(float force) {
Toast.makeText(this, "Motion detected", Toast.LENGTH_SHORT).show();
}

@Override
public void onStop() {
super.onStop();

//Check device supported Accelerometer senssor or not
if (AccelerometerManager.isListening()) {

//Start Accelerometer Listening
AccelerometerManager.stopListening();

Toast.makeText(this, "onStop Accelerometer Stopped", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (AccelerometerManager.isListening()) {
AccelerometerManager.stopListening();

Toast.makeText(this, "onDestroy Accelerometer Stopped", Toast.LENGTH_SHORT).show();
}
}
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.spaceo.shakedetectiondemo">

<uses-permission android:name="android.permission.READ_PHONE_STATE"/>

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>

<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>

</manifest>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="Main Screen"
android:textColor="@android:color/black"
android:textSize="32sp"/>
</LinearLayout>

Once you successfully implement this code, you can easily integrate Android Accelerometer in your app. Though, If you’d like to know how you can add different features of shake detection, you can consult with an Android app development company, who have hands-on experience in developing accelerometer apps and can offer a right suggestion for your mobile app.

Get a free copy of Shake Detection Demo From Github.

This page was last edited on October 29th, 2018, at 8:09.
 
 

Have an App Idea?

Get your free consultation now