How to use Accelerometer Sensor in Android


So you would like to use Accelerometer in the Android device and was searching for an example code snippet for the same? Well, you have come to the right place. In this post we will see how to use Accelerometer in your projects.

For learning, I will show you how to create a simple app which increments a counter on the app screen whenever there is acceleration sensed in any particular axis.

Let’s create view for the activity using following layout:


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:paddingBottom="@dimen/activity_vertical_margin"

android:paddingLeft="@dimen/activity_horizontal_margin"

android:paddingRight="@dimen/activity_horizontal_margin"

android:paddingTop="@dimen/activity_vertical_margin"

tools:context=".MainActivity" >

&nbsp;

<TextView

android:id="@+id/txtCount"

style="@style/Count"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_alignParentLeft="true"

android:layout_alignParentRight="true"

android:text="@string/txtCount" />

&nbsp;

<TextView

android:id="@+id/textView1"

style="@style/steps"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_below="@+id/txtCount"

android:layout_centerHorizontal="true"

android:text="@string/txtSteps" />

&nbsp;

<Button

android:id="@+id/btnStart"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_alignLeft="@+id/txtCount"

android:layout_alignRight="@+id/txtCount"

android:layout_below="@+id/textView1"

android:layout_marginTop="34dp"

android:text="@string/strStop" />

&nbsp;

<Button

android:id="@+id/btnReset"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_alignLeft="@+id/btnStart"

android:layout_alignRight="@+id/btnStart"

android:layout_below="@+id/btnStart"

android:text="@string/reset" />

&nbsp;

</RelativeLayout>

‘txtCount’ is the TextView which will show our counter value, and there are two buttons, one for start/stop and other for counter reset function.

Here is the strings.xml file content for our app:


<?xml version="1.0" encoding="utf-8"?>

<resources>

&nbsp;

<string name="app_name">Accelerometer</string>

<string name="action_settings">Settings</string>

<string name="txtCount">0</string>

<string name="strStart">Start</string>

<string name="txtSteps">Steps</string>

<string name="reset">Reset</string>

<string name="strStop">Stop</string>

</resources>

In your main activity class, in onCreate() method, initialize accelerometer sensor like this:


// Initialize Accelerometer sensor
 mInitialized = false;
 mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
 mAccelerometer = mSensorManager
 .getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
 startSensor();

I hope it is understood that you will have to initialize mSensorManager and mAccelerometer variables in your activity class like this:


private boolean mInitialized; // used for initializing sensor only once

private SensorManager mSensorManager;

private Sensor mAccelerometer;

And here is our startSensor() method:


private void startSensor() {
mSensorManager.registerListener(this, mAccelerometer,
SensorManager.SENSOR_DELAY_NORMAL);
 }

Now we have successfully initialized sensor, next comes the actual meat of the app. Override onSensorChanged() method which is the main callback method whenever there is change detected by sensor (in its sensing property). Here is the complete code for the method with self explanatory comments.


@Override
 public void onSensorChanged(SensorEvent event) {
 // event object contains values of acceleration, read those
 double x = event.values[0];
 double y = event.values[1];
 double z = event.values[2];

 final double alpha = 0.8; // constant for our filter below

double[] gravity = {0,0,0};

 // Isolate the force of gravity with the low-pass filter.
 gravity[0] = alpha * gravity[0] + (1 - alpha) * event.values[0];
 gravity[1] = alpha * gravity[1] + (1 - alpha) * event.values[1];
 gravity[2] = alpha * gravity[2] + (1 - alpha) * event.values[2];

// Remove the gravity contribution with the high-pass filter.
 x = event.values[0] - gravity[0];
 y = event.values[1] - gravity[1];
 z = event.values[2] - gravity[2];

if (!mInitialized) {
 // sensor is used for the first time, initialize the last read values
 mLastX = x;
 mLastY = y;
 mLastZ = z;
 mInitialized = true;
 } else {
 // sensor is already initialized, and we have previously read values.
 // take difference of past and current values and decide which
 // axis acceleration was detected by comparing values

double deltaX = Math.abs(mLastX - x);
 double deltaY = Math.abs(mLastY - y);
 double deltaZ = Math.abs(mLastZ - z);
 if (deltaX < NOISE)
 deltaX = (float) 0.0;
 if (deltaY < NOISE)
 deltaY = (float) 0.0;
 if (deltaZ < NOISE)
 deltaZ = (float) 0.0;
 mLastX = x;
 mLastY = y;
 mLastZ = z;

if (deltaX > deltaY) {
 // Horizontal shake
 // do something here if you like

} else if (deltaY > deltaX) {
 // Vertical shake
 // do something here if you like

} else if ((deltaZ > deltaX) && (deltaZ > deltaY)) {
 // Z shake
 stepsCount = stepsCount + 1;
 if (stepsCount > 0) {
 txtCount.setText(String.valueOf(stepsCount));
 }

// Just for indication purpose, I have added vibrate function
 // whenever our count moves past multiple of 10
 if ((stepsCount % 10) == 0) {
 Util.Vibrate(this, 100);
 }
 } else {
 // no shake detected
 }
 }
 }

Run it on actual device (emulator doesn’t support acceleration sensing) and shake your phone and count will get incremented. Based on sensor’s sensitivity your count may increment fast enough or you might have to shake your phone real hard. Play around with the NOISE constant in your code, which should be defined like this in your activity class:


private final float NOISE = (float) 2.0;

Please note that this is not the complete code for accelerometer feature. I have tried to show a basic minimal code for reading sensor values. In real world apps you will have to improve the filter for reducing noise and user errors while handing and shaking the phone. It can get too complex for use like counting walk steps, run steps etc.

Well, I didn’t want to use it for my apps, however if you get any good references or tutorials about how to improve it for such apps, please push those in comments.

Advertisements
About

An all round Software Engineer with 8 years of software development experience looking to work on exciting projects with exciting clients. Full of energy, experience, hard work and enthusiasm, I need a new challenge and want to work in the heart of the web software industry.

Tagged with: , , ,
Posted in Android
4 comments on “How to use Accelerometer Sensor in Android
  1. Anonymous says:

    very good, thx

  2. thanx for this great tutorial , sir i want to use accelerometer for counting steps i am not finding any simple tutorial will you please guide me, i just want to show step count in a textview for every step of user. please help .

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Visit My Website
Posts
Categories

Enter your email address to follow this blog and receive notifications of new posts by email.

Join 136 other followers

%d bloggers like this: