title: Detect Movement Accurately using Accelerometer in Android
body: <p>I am implementing a demo TIMER, with Vibration ( at a particular condition ), When I press start my timer starts running.. and when I stop it using stop button, it simply stops. </p>
  
  <p>Now I have to integrate a functionality, when the person shifts the device <strong>(while the Timer is running)</strong>, it should reset the timer. It is working pretty good, but the accelerometer functionality is not working absolutely accurate. It needs a fast jerk to reset the timer.</p>
  
  <p>Suggest me a good solution for the same.</p>
  
  <p>Here is my code</p>
  
  <pre><code>public class SensorAccelerometer implements SensorEventListener {
  
      private Context context;
      private SensorManager sensorManager;
      private Sensor accelerometer;
      private TextView timelabel;
      private Handler mHandler;
      Runnable run;
  
      private float mLastX, mLastY, mLastZ;
      private final float NOISE = (float) 3.0;
  
      public SensorAccelerometer(Context context) {
  
      }
  
  
      public SensorAccelerometer(Context context,TextView timelabel, Handler mHandler2, Runnable mUpdateTimeTask) {
          // TODO Auto-generated constructor stub
  
          this.context = context;
          this.timelabel = timelabel;
          this.mHandler = mHandler2;
          this.run = mUpdateTimeTask;
  
          initialiseSensor();
      }
  
  
      public void initialiseSensor(){
          sensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
          accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ALL);
          sensorManager.registerListener(this, accelerometer,SensorManager.SENSOR_DELAY_NORMAL);
      }
  
      public void unregisterSensor(){
          sensorManager.unregisterListener(this);
          Toast.makeText(context, "Sensor Stopped..", Toast.LENGTH_SHORT).show();
      }
  
  
      public void onAccuracyChanged(Sensor sensor, int accuracy) {
  
      }
  
      public void onSensorChanged(SensorEvent event) {
      float x = event.values[0];
      float y = event.values[1];
      float z = event.values[2];
  
      mAccelLast=mAccelCurrent;
  
      mAccelCurrent = FloatMath.sqrt(x*x + y*y + z*z);
      float delta = mAccelCurrent - mAccelLast;
      mAccel = mAccel * 0.9f + delta;
  
      if(mAccel&gt;0.5){
          TimerActivity.mStartTime = SystemClock.uptimeMillis();
          mHandler.removeCallbacks(run);
          mHandler.postDelayed(run, 100);
      }
  </code></pre>
  
  <p>}</p>
  
  <p>Timer Activity</p>
  
  <pre><code>public class TimerActivity extends Activity {
  
      public static long mStartTime = 0L;
      private TextView mTimerLabel;
  
      private Handler mHandler = new Handler();
  
      String timerStop1;
  
      @Override
      public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.main);
  
          mTimerLabel = (TextView) findViewById(R.id.textTimer);
  
          Button timerStartButton = (Button) findViewById(R.id.btnTimer);       
          timerStartButton.setOnClickListener(new View.OnClickListener() {
              public void onClick(View view){
  
                  if(mStartTime == 0L){
                      mStartTime = SystemClock.uptimeMillis();
                      mHandler.removeCallbacks(mUpdateTimeTask);
                      mHandler.postDelayed(mUpdateTimeTask, 100);
  
                      //activating the sensor and the acclerometer
                      SensorAccelerometer acc = new SensorAccelerometer(view.getContext(), mTimerLabel,mHandler,mUpdateTimeTask);
                  }                                   
              }
          }); 
  
          Button timerStopButton = (Button) findViewById(R.id.btnTimerStop);       
          timerStopButton.setOnClickListener(new View.OnClickListener() {
              public void onClick(View view){
  
                  mHandler.removeCallbacks(mUpdateTimeTask);
                  mTimerLabel.setText(timerStop1);
                  mStartTime = 0L;
  
                  SensorAccelerometer scc = new SensorAccelerometer(view.getContext(),mTimerLabel,mHandler,mUpdateTimeTask);
                  scc.unregisterSensor();
              }
          }); 
  
      } 
  
  
      private Runnable mUpdateTimeTask = new Runnable(){
  
          public void run() {
  
              final long start = mStartTime;
              long millis = SystemClock.uptimeMillis()- start;
  
              int seconds = (int) (millis / 1000);
              int minutes = seconds / 60;
              seconds = seconds % 60;
  
              mTimerLabel.setText("" + minutes + ":"
                                    + String.format("%02d", seconds));                    
  
              timerStop1 = minutes + ":"
                        + String.format("%02d", seconds);
  
              mHandler.postDelayed(this, 200);            
  
          }   
      }; 
  
      protected void onPause() {
          super.onPause();
          SensorAccelerometer scc = new SensorAccelerometer(this,mTimerLabel,mHandler,mUpdateTimeTask);
          scc.unregisterSensor();
      };
  
  } 
  </code></pre>