title: How to read Android accelerometer values in a stable and accurate way?
body: <p>In a my project I am trying to control a car using data obtained through the accelerometer of an Android device. (Left, Right, Forward, Reverse). Even though I have managed to read values from the accelerometer the readings are subject to frequent changes even the device is in a stable position. Can someone provide me a better way to do this?</p>
  
  <p>Following is the code that I have used</p>
  
  <pre><code>import android.content.Context;
  import android.hardware.Sensor;
  import android.hardware.SensorEvent;
  import android.hardware.SensorEventListener;
  import android.hardware.SensorManager;
  
  public class AccelerometerService {
      private static SensorManager sensorManager;
      private static SensorEventListener sensorEventListener;
      private static boolean started = false;
  
      private static float[] accelerometer = new float[3];
      private static float[] magneticField = new float[3];
  
      private static float[] rotationMatrix = new float[9];
      private static float[] inclinationMatrix = new float[9];
      private static float[] attitude = new float[3];
  
      private final static double RAD2DEG = 180/Math.PI;
  
      private static int initialAzimuth = 0;
      private static int initialPitch = 0;
      private static int initialRoll = 0;
  
      private static int[] attitudeInDegrees = new int[3];
  
      public static void start(final Context applicationContext) {
          if(started) {
              return;
          }
  
          sensorManager = (SensorManager) applicationContext
                  .getSystemService(Context.SENSOR_SERVICE);
  
          sensorEventListener = new SensorEventListener() {
  
              @Override
              public void onSensorChanged(SensorEvent event) {
  
                  int type = event.sensor.getType();
                  if(type == Sensor.TYPE_MAGNETIC_FIELD) {
                      magneticField = event.values.clone();
                  } 
                  if(type == Sensor.TYPE_ACCELEROMETER) {
                      accelerometer = event.values.clone();
                  }
  
                  SensorManager.getRotationMatrix(rotationMatrix, inclinationMatrix, accelerometer, magneticField);
                  SensorManager.getOrientation(rotationMatrix, attitude);
  
                  attitudeInDegrees[0] =  (int) Math.round(attitude[0] * RAD2DEG);    //azimuth
                  attitudeInDegrees[1] = (int) Math.round(attitude[1] * RAD2DEG);     //pitch
                  attitudeInDegrees[2] = (int) Math.round(attitude[2] * RAD2DEG);     //roll
              }
  
              @Override
              public void onAccuracyChanged(Sensor sensor, int accuracy) {
  
              }
          };
          sensorManager.registerListener(sensorEventListener,
                  sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
                  SensorManager.SENSOR_DELAY_UI);
          sensorManager.registerListener(sensorEventListener,
                  sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD),
                  SensorManager.SENSOR_DELAY_UI);
  
          started = true;
      }
  
      public static boolean getStarted() {
          return started;
      }
  
      public static void stop() {
          if(started) {
          sensorManager.unregisterListener(sensorEventListener);
          started = false;
          }
      }
  }
  </code></pre>