title: Android: Shake Detector too Sensitive
body: <p>I'm trying to detect a shake - and i'm using the following code,
  it works very good, but in some devices (Galaxy note 2 for example) it detects the shake too soon (in some cases - when i just hold the phone still)</p>
  
  <p>main.java:</p>
  
  <pre><code>ShakeListener mShaker = new ShakeListener(this);
       mShaker.setOnShakeListener(new ShakeListener.OnShakeListener () {
           public void onShake()
           {
          // Some code...
           }
       });
  }
  </code></pre>
  
  <p>ShakeListener.java :</p>
  
  <pre><code>package com.my.app;
  
  import android.hardware.Sensor;
  import android.hardware.SensorEvent;
  import android.hardware.SensorEventListener;
  import android.hardware.SensorManager;
  import android.widget.Toast;
  import android.content.Context;
  import java.lang.UnsupportedOperationException;
  
  public class ShakeListener implements SensorEventListener
  {
        private static final int FORCE_THRESHOLD = 700;
        private static final int TIME_THRESHOLD = 100;
        private static final int SHAKE_TIMEOUT = 500;
        private static final int SHAKE_DURATION = 1000;
        private static final int SHAKE_COUNT = 5;
  
        private SensorManager mSensorMgr;
        private float mLastX=-1.0f, mLastY=-1.0f, mLastZ=-1.0f;
        private long mLastTime;
        private OnShakeListener mShakeListener;
        private Context mContext;
        private int mShakeCount = 0;
        private long mLastShake;
        private long mLastForce;
  
        public interface OnShakeListener
        {
          public void onShake();
        }
  
        public ShakeListener(Context context)
        {
          mContext = context;
          resume();
        }
  
        public void setOnShakeListener(OnShakeListener listener)
        {
          mShakeListener = listener;
        }
  
        public void resume() {
          mSensorMgr = (SensorManager)mContext.getSystemService(Context.SENSOR_SERVICE);
          if (mSensorMgr == null) {
            throw new UnsupportedOperationException("Sensors not supported");
          }
          boolean supported = false;
          try {
          supported = mSensorMgr.registerListener(this, mSensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_GAME);
          } catch (Exception e) {Toast.makeText(mContext, "Shaking not supported", Toast.LENGTH_LONG).show();}
  
          if ((!supported)&amp;&amp;(mSensorMgr != null)) mSensorMgr.unregisterListener(this);
        }
  
        public void pause() {
          if (mSensorMgr != null) {
            mSensorMgr.unregisterListener(this);
            mSensorMgr = null;
          }
        }
  
        public void onAccuracyChanged(Sensor sensor, int accuracy) { }
  
        public void onSensorChanged(SensorEvent event)
        {
          if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER)
                return;
          long now = System.currentTimeMillis();
  
          if ((now - mLastForce) &gt; SHAKE_TIMEOUT) {
            mShakeCount = 0;
          }
  
          if ((now - mLastTime) &gt; TIME_THRESHOLD) {
            long diff = now - mLastTime;
            float speed = Math.abs(event.values[0] + event.values[1] + event.values[2] - mLastX - mLastY - mLastZ) / diff * 10000;
            if (speed &gt; FORCE_THRESHOLD) {
              if ((++mShakeCount &gt;= SHAKE_COUNT) &amp;&amp; (now - mLastShake &gt; SHAKE_DURATION)) {
                mLastShake = now;
                mShakeCount = 0;
                if (mShakeListener != null) {
                  mShakeListener.onShake();
                }
              }
              mLastForce = now;
            }
            mLastTime = now;
            mLastX = event.values[0];
            mLastY = event.values[1];
            mLastZ = event.values[2];
          }
        }
  }
  </code></pre>