/**
*
@author Ranger * 搖動類 * */ public class Shaker { /** * 傳感器管理 */ private SensorManager mgr = null; /** *最後搖動的時間 */ private long lastShakeTimestamp = 0; /** * 偏移量設置 */ private double threshold = 1.0d; /** * 搖動的時間間隔設置 */ private long gap = 0; /** * 回調 */ private Shaker.Callback cb = null; /** * 變量控制,防止屢次啓動 */ private boolean mPause = false; /** * 傳感器類 * @param ctxt 上下文 * @param threshold 偏移量 * @param gap 傳感器的時間 * @param cb 回調方法 */ public Shaker(Context ctxt, double threshold, long gap, Shaker.Callback cb) { this.threshold = threshold * threshold; this.threshold = this.threshold * SensorManager.GRAVITY_EARTH * SensorManager.GRAVITY_EARTH; this.gap = gap; this.cb = cb; //註冊傳感器 mgr = (SensorManager) ctxt.getSystemService(Context.SENSOR_SERVICE); //註冊傳感器的監聽事件 mgr.registerListener(listener, mgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_UI); } public void close() { mgr.unregisterListener(listener); } private void isShaking() { long now = SystemClock.uptimeMillis(); if (lastShakeTimestamp == 0) { lastShakeTimestamp = now; if (cb != null) { cb.shakingStarted(); } } else { lastShakeTimestamp = now; } } private void isNotShaking() { long now = SystemClock.uptimeMillis(); if (lastShakeTimestamp > 0) { if (now - lastShakeTimestamp > gap) { lastShakeTimestamp = 0; if (cb != null) { cb.shakingStopped(); } } } } public interface Callback { void shakingStarted(); void shakingStopped(); } private SensorEventListener listener = new SensorEventListener() { public void onSensorChanged(SensorEvent e) { if (e.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { double netForce = e.values[0] * e.values[0]; netForce += e.values[1] * e.values[1]; netForce += e.values[2] * e.values[2]; //偏移量,X^2 + Y^2 + Z^2 與最大的偏移量threshold相比,若是超過就做爲在搖動 if ((threshold < netForce) && !mPause) { isShaking(); } else { isNotShaking(); } } } public void onAccuracyChanged(Sensor sensor, int accuracy) { // unused } }; public void resume() { mPause = false; } public void pause() { mPause = true; } }