Monday, January 25, 2010

Android Accelerometer and Orientation Example

Following is an example of how to use the Android accelerometer and orientation API’s. This example is based on Frank Ableson’s “Tapping into Android’s sensors” article over at IBM DeveloperWorks. I’ve made a change to the UI to use the Android TableView and implemented it as a Resource.

To get going, all you need to do is
  1. Create a new Android project 
  2. Replace the contents of main.xml with the xml in this sample 
  3. Replace the contents of your Activity class with the code in this sample

    Following is the new main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:stretchColumns="1">

        <TableRow>
            <TextView
                android:id="@+id/accelerometer_label"
                android:layout_column="1"
                android:text="Accelerometer"
                android:textSize="9pt"
                android:padding="3dip" />
        </TableRow>
      
        <TableRow>
            <TextView
                android:id="@+id/accel_x_label"
                android:layout_column="1"
                android:text="X:"
                android:textSize="8pt"
                android:padding="3dip" />
            <TextView
                android:id="@+id/accel_x_value"
                android:gravity="right"
                android:textSize="8pt"
                android:padding="3dip" />
        </TableRow>

        <TableRow>
            <TextView
                android:id="@+id/accel_y_label"
                android:layout_column="1"
                android:text="Y:"
                android:textSize="8pt"
                android:padding="3dip" />
            <TextView
                android:id="@+id/accel_y_value"
                android:gravity="right"
                android:textSize="8pt"
                android:padding="3dip" />
        </TableRow>

        <TableRow>
            <TextView
                android:id="@+id/accel_z_label"
                android:layout_column="1"
                android:text="Z:"
                android:textSize="8pt"
                android:padding="3dip" />
            <TextView
                android:id="@+id/accel_z_value"
                android:gravity="right"
                android:textSize="8pt"
                android:padding="3dip" />
        </TableRow>

        <View
            android:layout_height="2dip"
            android:background="#FF909090" />
          
    <TableRow>
            <TextView
                android:id="@+id/orientation_label"
                android:layout_column="1"
                android:text="Orientation"
                android:textSize="9pt"
                android:padding="3dip" />
        </TableRow>
      
        <TableRow>
            <TextView
                android:id="@+id/orient_x_label"
                android:layout_column="1"
                android:text="X:"
                android:textSize="8pt"
                android:padding="3dip" />
            <TextView
                android:id="@+id/orient_x_value"
                android:gravity="right"
                android:textSize="8pt"
                android:padding="3dip" />
        </TableRow>

        <TableRow>
            <TextView
                android:id="@+id/orient_y_label"
                android:layout_column="1"
                android:text="Y:"
                android:textSize="8pt"
                android:padding="3dip" />
            <TextView
                android:id="@+id/orient_y_value"
                android:gravity="right"
                android:textSize="8pt"
                android:padding="3dip" />
        </TableRow>

        <TableRow>
            <TextView
                android:id="@+id/orient_z_label"
                android:layout_column="1"
                android:text="Z:"
                android:textSize="8pt"
                android:padding="3dip" />
            <TextView
                android:id="@+id/orient_z_value"
                android:gravity="right"
                android:textSize="8pt"
                android:padding="3dip" />
        </TableRow>

    </TableLayout>





    Following is the new Android Activity Java class

    package com.blogspot.mobilestrategist;



    import com.blogspot.mobilestrategist.R;

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

    public class AccelOrientExample extends Activity implements SensorEventListener {
    // Accelerometer X, Y, and Z values
    private TextView accelXValue;
    private TextView accelYValue;
    private TextView accelZValue;
    // Orientation X, Y, and Z values
    private TextView orientXValue;
    private TextView orientYValue;
    private TextView orientZValue;
    private SensorManager sensorManager = null;
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            // Get a reference to a SensorManager
            sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
            setContentView(R.layout.main);
          
            // Capture accelerometer related view elements
            accelXValue = (TextView) findViewById(R.id.accel_x_value);
            accelYValue = (TextView) findViewById(R.id.accel_y_value);
            accelZValue = (TextView) findViewById(R.id.accel_z_value);
          
            // Capture orientation related view elements
            orientXValue = (TextView) findViewById(R.id.orient_x_value);
            orientYValue = (TextView) findViewById(R.id.orient_y_value);
            orientZValue = (TextView) findViewById(R.id.orient_z_value);
          
            // Initialize accelerometer related view elements
            accelXValue.setText("0.00");
            accelYValue.setText("0.00");
            accelZValue.setText("0.00");
          
            // Initialize orientation related view elements
            orientXValue.setText("0.00");
            orientYValue.setText("0.00");
            orientZValue.setText("0.00");      
        }
      
        // This method will update the UI on new sensor events
        public void onSensorChanged(SensorEvent sensorEvent) {
        synchronized (this) {
        if (sensorEvent.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
        accelXValue.setText(Float.toString(sensorEvent.values[0]));
        accelYValue.setText(Float.toString(sensorEvent.values[1]));
        accelZValue.setText(Float.toString(sensorEvent.values[2]));    
        }
        
        if (sensorEvent.sensor.getType() == Sensor.TYPE_ORIENTATION) {
        orientXValue.setText(Float.toString(sensorEvent.values[0]));
        orientYValue.setText(Float.toString(sensorEvent.values[1]));
        orientZValue.setText(Float.toString(sensorEvent.values[2]));    
        }
        }
        }
      
        // I've chosen to not implement this method
        public void onAccuracyChanged(Sensor arg0, int arg1) {
    // TODO Auto-generated method stub
    }
      
        @Override
        protected void onResume() {
        super.onResume();
        // Register this class as a listener for the accelerometer sensor
        sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
        // ...and the orientation sensor
        sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION), SensorManager.SENSOR_DELAY_NORMAL);
        }
      
        @Override
        protected void onStop() {
        // Unregister the listener
        sensorManager.unregisterListener(this);
        super.onStop();
        }
    }

    22 comments:

    1. Thanks for the code, I tried it and it works great.

      Am building an app where the droid simulates an airplane yoke. It is not an airplane app, but I need the same behavior as an airplane. Twist the phone left or right, and get a roll angle relative to the phone. pitch the phone up or down and get a pitch angle.

      Thanks in advance.
      Raider

      ReplyDelete
    2. Hi Raider,

      I'm glad you found the example useful. Your app sounds interesting. If you publish it to Android Market, post back.

      ReplyDelete
    3. Thank you very much for this tutorial. Works very fine and helped me a lot! Regards, Sven

      ReplyDelete
    4. Thanks, this was very helpful! Got me off the ground.

      ReplyDelete
    5. this is a great and simple example I liked it, but i still have to figure out how to store the data in an external storage :S, seems like its not easy on platform 2.1

      thanks for sharing

      ReplyDelete
    6. www.mobiappmax.com

      really want to say everyone that this website is one stop website for different kind ofmobile applications like gaming applications Google translator, dictionary, sports news, world news, currency converter, and many more it is really a great and appreciable website where you can get all kind of web apps you jus name it they have it.

      ReplyDelete
    7. hey.. in getting error in this line

      accelXValue = (TextView) findViewById(R.id.accel_x_value);

      error: id cannot be resolved or not in the field

      solution pls...

      ReplyDelete
    8. hi , it got this error : " the application ... has not responded and needs to be closed " sth like that .

      ReplyDelete
    9. This was a very simple helpful example. Thanks!

      ReplyDelete
    10. Orientation sensor doesn't give result while Accelarometer sensor gives result.

      Orientation Sensor gives:
      x 0.00
      y 0.00
      z 0.00

      PLEASE HELP ...

      ReplyDelete
    11. How do I implement both OnClickListener, and SensorEventListener? Please help!

      ReplyDelete
    12. Thanks for the tutorial, this was just what I needed to get started working with the accelerometer.

      ReplyDelete
    13. I am building a game in which the user controls the sprite using accelerometer sensor. Your tutorial was very helpfull. Thanks a lot!!!

      ReplyDelete
    14. I tried that, but the app crush immediately.
      I tried to add permissions to the Manifest, but w/o success.

      Can someone help me?

      ReplyDelete
    15. hi...
      i successfully created the application. but no results is on Emulator screen..

      Any ideas?

      regards

      ReplyDelete
    16. Doesn't work on Emulator I think. I tried too, but Orientation Sensor doesn't work and Accelerometar give this:
      X: 9.77622
      Y: 0.0
      Z: 0.813417
      all the time

      ReplyDelete
    17. Yes, I am now sure: IT DOESN'T WORK ON EMULATOR!!!

      ReplyDelete
    18. maybe You can help me. I have problem with sensor. I use geomagnetic field and accelerometer, and thats works but the problem is that when the phone lie on the table and nothing changes, no movements - values are changing. when i should have 120 degrees i have 117, 118,117,120,122,121 itd...
      it's very undecided sensor. ;)
      Please help me.

      ReplyDelete
    19. You should unregister the listeners on the onPause method

      ReplyDelete
    20. The orientation sensor is deprecated these days. Anyone know of any code that works but doesn't use it?

      ReplyDelete

    ShareThis