Sensor

Android Accelerometer Example

The Android platform provides several sensors that let you monitor the motion of a device. Some of these sensors are hardware-based and some are software-based.

The Android platform supports three broad categories of sensors:
• Motion sensors
• Environmental sensors thermometers.
• Position sensors

Motion sensors are useful for monitoring device movement, such as tilt, shake, rotation, or swing. In our example, we are going to disscuss about a motion – hardware based sensor, the Android Accelerometer sensor.
This sensor can measure the acceleration force in m/s2 that is applied to a device on all three physical axes (x, y, and z), including the force of gravity.

So, in this example, we will make an Activity that can listen to Android Accelerometer changes, that can show the current and max x,y,z values, and can vibrate when the accelerometer values are over a certain threshold.

For this tutorial, we will use the following tools in a Windows 64-bit platform:

  • JDK 1.7
  • Eclipse 4.2 Juno
  • Android SDK 4.4

Let’s take a closer look:

1. Create a New Android Application Project

Tip
You may skip project creation and jump directly to the beginning of the example below.

Open Eclipse IDE and go to File → New → Project → Android Application Project.

File → New → Project → Android Application Project.
Figure 1. Create a new Android project

Specify the name of the application, the project and the package and then click Next.

Specify the name of the application
Figure 2. Create a new Android project name

In the next window, the “Create Activity” option should be checked. The new created activity will be the main activity of your project. Then press Next button.

Create Activity
Figure 3. Configure the project

In “Configure Launcher Icon” window you should choose the icon you want to have in your app. We will use the default icon of android, so click Next.

Configure Launcher Icon
Figure 4. Configure the launcher icon

Select the “Blank Activity” option and press Next.

Blank Activity
Figure 5. Create the activity and select its type

You have to specify a name for the new Activity and a name for the layout description of your app. The .xml file for the layout will automatically be created in the res/layout folder. It will also be created a fragment layout xml, that we are not going to use in this project and you can remove it if you want. Then press Finish.

Name for the new Activity
Figure 6. Create a new blank activity

You can see the structure of the project:

The structure of the project
Figure 7. The tree of the project

2. Creating the layout of the main Activity

We are going to make a very simple layout xml for our activity, that only consists of a LinearLayout that contains the TextViews for the labels and the values of the maximum acceleration values, and three LinearLayouts that contain the TextViews for the labels and the values of the current acceleration values.

Open res/layout/activity_main.xml, go to the respective xml tab and paste the following:

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:layout_gravity="center"
    android:background="#ffffff"
    android:gravity="center"
    android:orientation="vertical"
    android:paddingTop="20dp" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginBottom="10dp"
        android:text="Max Acceleration:"
        android:textSize="20dp" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginTop="20dp"
        android:text="Max Acceleration: X-Axis"
        android:textSize="15dp" />

    <TextView
        android:id="@+id/maxX"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginTop="10dp"
        android:text="0.0"
        android:textSize="20dp" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginTop="20dp"
        android:text="Max Acceleration: Y-Axis"
        android:textSize="15dp" />

    <TextView
        android:id="@+id/maxY"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginTop="10dp"
        android:text="0.0"
        android:textSize="20dp" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginTop="20dp"
        android:text="Max Acceleration: Z-Axis"
        android:textSize="15dp" />

    <TextView
        android:id="@+id/maxZ"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginTop="10dp"
        android:text="0.0"
        android:textSize="20dp" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginBottom="10dp"
        android:layout_marginTop="30dp"
        android:text="Current Acceleration:"
        android:textSize="20dp" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#ffffff"
        android:gravity="center|top"
        android:orientation="horizontal" >

        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="0.33"
            android:background="#ffffff"
            android:gravity="center"
            android:orientation="vertical" >

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:layout_marginTop="10dp"
                android:text="X-Axis"
                android:textSize="15dp" />

            <TextView
                android:id="@+id/currentX"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:layout_marginTop="10dp"
                android:text="0.0"
                android:textSize="15dp" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="0.33"
            android:background="#ffffff"
            android:gravity="center"
            android:orientation="vertical" >

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:layout_marginTop="10dp"
                android:text="Y-Axis"
                android:textSize="15dp" />

            <TextView
                android:id="@+id/currentY"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:layout_marginTop="10dp"
                android:text="0.0"
                android:textSize="15dp" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="0.33"
            android:background="#ffffff"
            android:gravity="center"
            android:orientation="vertical" >

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:layout_marginTop="10dp"
                android:text="Z-Axis"
                android:textSize="15dp" />

            <TextView
                android:id="@+id/currentZ"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:layout_marginTop="10dp"
                android:text="0.0"
                android:textSize="15dp" />
        </LinearLayout>
    </LinearLayout>

</LinearLayout>

3. Creating the source code of the main Activity

Open src/com.javacodegeeks.androidaccelerometerexample/AndroidVideoViewExample.java file and paste the code below.

AndroidAccelerometerExample .java

package com.javacodegeeks.androidaccelerometerexample;

import android.app.Activity;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.os.Vibrator;
import android.widget.TextView;

public class AndroidAccelerometerExample extends Activity implements SensorEventListener {

	private float lastX, lastY, lastZ;

	private SensorManager sensorManager;
	private Sensor accelerometer;

	private float deltaXMax = 0;
	private float deltaYMax = 0;
	private float deltaZMax = 0;

	private float deltaX = 0;
	private float deltaY = 0;
	private float deltaZ = 0;

	private float vibrateThreshold = 0;

	private TextView currentX, currentY, currentZ, maxX, maxY, maxZ;

	public Vibrator v;

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

		sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
		if (sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null) {
			// success! we have an accelerometer

			accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
			sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL);
			vibrateThreshold = accelerometer.getMaximumRange() / 2;
		} else {
			// fai! we dont have an accelerometer!
		}
		
		//initialize vibration
		v = (Vibrator) this.getSystemService(Context.VIBRATOR_SERVICE);

	}

	public void initializeViews() {
		currentX = (TextView) findViewById(R.id.currentX);
		currentY = (TextView) findViewById(R.id.currentY);
		currentZ = (TextView) findViewById(R.id.currentZ);

		maxX = (TextView) findViewById(R.id.maxX);
		maxY = (TextView) findViewById(R.id.maxY);
		maxZ = (TextView) findViewById(R.id.maxZ);
	}

	//onResume() register the accelerometer for listening the events
	protected void onResume() {
		super.onResume();
		sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL);
	}

	//onPause() unregister the accelerometer for stop listening the events
	protected void onPause() {
		super.onPause();
		sensorManager.unregisterListener(this);
	}

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

	@Override
	public void onSensorChanged(SensorEvent event) {

		// clean current values
		displayCleanValues();
		// display the current x,y,z accelerometer values
		displayCurrentValues();
		// display the max x,y,z accelerometer values
		displayMaxValues();

		// get the change of the x,y,z values of the accelerometer
		deltaX = Math.abs(lastX - event.values[0]);
		deltaY = Math.abs(lastY - event.values[1]);
		deltaZ = Math.abs(lastZ - event.values[2]);

		// if the change is below 2, it is just plain noise
		if (deltaX < 2)
			deltaX = 0;
		if (deltaY < 2)
			deltaY = 0;
		if (deltaZ  vibrateThreshold) || (deltaY > vibrateThreshold) || (deltaZ > vibrateThreshold)) {
			v.vibrate(50);
		}
	}

	public void displayCleanValues() {
		currentX.setText("0.0");
		currentY.setText("0.0");
		currentZ.setText("0.0");
	}

	// display the current x,y,z accelerometer values
	public void displayCurrentValues() {
		currentX.setText(Float.toString(deltaX));
		currentY.setText(Float.toString(deltaY));
		currentZ.setText(Float.toString(deltaZ));
	}

	// display the max x,y,z accelerometer values
	public void displayMaxValues() {
		if (deltaX > deltaXMax) {
			deltaXMax = deltaX;
			maxX.setText(Float.toString(deltaXMax));
		}
		if (deltaY > deltaYMax) {
			deltaYMax = deltaY;
			maxY.setText(Float.toString(deltaYMax));
		}
		if (deltaZ > deltaZMax) {
			deltaZMax = deltaZ;
			maxZ.setText(Float.toString(deltaZMax));
		}
	}
}

Let’s see in detail the code above.

We set the activity_main.xml layout and we initialize our basic views by:

setContentView(R.layout.activity_main);
initializeViews();

Then, we want to check if our device supports the accelerometer sensor, and can run the specific service. If our device supports accerelometer, we initialize our sensorManager in order to bind the sensor to listen to the accelerometer events. So, we register a specific listener to catch the events by writing in the onCreate() method the following lines:

		sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
		if (sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null) {
			// success! we have an accelerometer

			accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
			sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL);
			vibrateThreshold = accelerometer.getMaximumRange() / 2;
		} else {
			// fai! we dont have an accelerometer!
		}

Generally, we do not want these kind of listeners to run to our device continually, because most of the times they appear to be energy and cpu consuming, so we are going to unregister our listener onPause() of our activity, and then register them back on, onResume() of our activity. So, we have to add:

	//onResume() register the accelerometer for listening the events
	protected void onResume() {
		super.onResume();
		sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL);
	}
	//onPause() unregister the accelerometer for stop listening the events
	protected void onPause() {
		super.onPause();
		sensorManager.unregisterListener(this);
	}

We, have now come to the point, that we should get the accelerometer events, and use them. We are going to get the x,z,y events, by using the event.values[0], event.values[1], event.values[2] accordingly. In fact, we want to save the difference between the values of two consecutive events, because this is metric that is going to show us, if we have shaked or tilted our mobile device. We have also to keep in mind, that this change might be almost impercetible for our human sences, but our mobile device will calculate even the slightest diffence, so we have to set a low threshold value, that will be considered as noise, and therefore will not be calculated by our device.

	@Override
	public void onSensorChanged(SensorEvent event) {

		// clean current values
		displayCleanValues();
		// display the current x,y,z accelerometer values
		displayCurrentValues();
		// display the max x,y,z accelerometer values
		displayMaxValues();

		// get the change of the x,y,z values of the accelerometer
		deltaX = Math.abs(lastX - event.values[0]);
		deltaY = Math.abs(lastY - event.values[1]);
		deltaZ = Math.abs(lastZ - event.values[2]);

		// if the change is below 2, it is just plain noise
		if (deltaX < 2)
			deltaX = 0;
		if (deltaY < 2)
			deltaY = 0;
		if (deltaZ < 2)
			deltaZ = 0;

		// set the last know values of x,y,z
		lastX = event.values[0];
		lastY = event.values[1];
		lastZ = event.values[2];

		vibrate();
	}

Our device will now vibrate, if we shake it enough! This will happen, only if we add in our code the line:

	// if the change in the accelerometer value is big enough, then vibrate!
	// our threshold is MaxValue/2
	public void vibrate() {
		if ((deltaX > vibrateThreshold) || (deltaY > vibrateThreshold) || (deltaZ > vibrateThreshold)) {
			v.vibrate(50);
		}
	}

4. Android Manifest

In order to enable the vibration feature, we have to grant permission to our application to use vibration. So, we have to add in the AndroidManifest.xml the following line: <uses-permission android:name="android.permission.VIBRATE" />"

We have also blocked our orientation to portait by adding the line: android:screenOrientation="portrait"

AndroidManifest.xml

    
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.javacodegeeks.androidaccelerometerexample"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="19" />

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

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name="com.javacodegeeks.androidaccelerometerexample.AndroidAccelerometerExample"
            android:configChanges="keyboardHidden|orientation|screenSize"
            android:label="@string/app_name"
            android:screenOrientation="portrait" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>
       

5. Build, compile and run

When we build, compile and run our project, the main Activity should look like this:

If we lay our mobile device on a table, this is metric that we will see. It is the z acceleration value and it is equal the force of gravity ( about 9.81 m/s2).
If we lay our mobile device on a table, this is metric that we will see. It is the z acceleration value and it is equal the force of gravity ( about 9.81 m/s2).

If we keep our mobile device on vertical position, this is metric that we will see. It is the y acceleration value and it is equal the force of gravity ( about 9.81 m/s2).
If we keep our mobile device on vertical position, this is metric that we will see. It is the y acceleration value and it is equal the force of gravity ( about 9.81 m/s2).

If we keep our mobile device on horizontal position, this is metric that we will see. It is the x acceleration value and it is equal the force of gravity ( about 9.81 m/s2).
If we keep our mobile device on horizontal position, this is metric that we will see. It is the x acceleration value and it is equal the force of gravity ( about 9.81 m/s2).

This is the main screen of the activity.
This is the main screen of the activity.

Download the Eclipse Project

This was an example of Android Accelerometer.

Download
You can download the full source code of this example here: AndroidAccelerometerExample.zip

Chryssa Aliferi

Chryssa is a Computer Science graduate from Athens University of Economic and Business. During her studies, Chryssa carried out a great variety of projects ranging from networking to software engineering. She is very keen on front end development especially on mobile technologies and web applications. She has worked as a junior Software Engineer in the telecommunications area and currently works as an Android Developer.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

4 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Narthana
Narthana
6 years ago

woowwww… what a great tutorial.. its working like a magic. thanks in advance… coolllllllllllll

Johirul Islam
Johirul Islam
6 years ago

Awesome

abeb
abeb
5 years ago

nic presentation on accelerometer. thanks you !

R02na
R02na
5 years ago

hello, first i wanted to say that this is a very good and claer tutorial thankyou :)
but i have a question,why when i run the emulator, i cant find the app on it?

Back to top button