Android搖一搖、螢幕方向的監聽

KosmoSakura發表於2019-01-28

踩坑記錄
這個工具類裡有兩個獨立的監聽

1.先貼程式碼

1.使用示例

1.例項化
UGravity gravity = new UGravity(this);
//監聽手機方向
gravity.setOrientationListener(orientation -> {
     //do sth
});
//監聽手機搖晃
gravity.setOnShakeListener(() -> {
    //do sth
});
2.用完清理
@Override
protected void onDestroy() {
    gravity.clear();
    super.onDestroy();
}

2.工具類原始碼

原理是使用Android的重力感測器返回值來判斷

/**
 * @Description: 重力監聽
 * @Author: Kosmos
 * @Date: 2019.01.28 11:56
 * @Email: KosmoSakura@gmail.com
 * 1.搖晃手機
 * 2.螢幕旋轉
 */
public class UGravity implements SensorEventListener {
    private static final int SPEED_SHRESHOLD = 2000;// 速度閾值
    private static final int UPTATE_INTERVAL_TIME = 200;// 檢測的時間間隔
    private SensorManager sorMgr;// 感測器管理器
    private OnShakeListener onShakeListener;//搖晃監聽器
    private OrientationListener orientationListener;////旋轉監聽器
    private long lastUpdateTime;//上次檢測時間
    // 手機上一個位置時重力感應座標
    private float lastX;
    private float lastY;
    private float lastZ;

    // 構造器
    public UGravity(Context context) {
        sorMgr = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
        // 註冊
        if (sorMgr != null) {
            sorMgr.registerListener(this,
                sorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_GAME);
        }
    }

    // 搖晃監聽介面
    public interface OnShakeListener {
        void onShake();
    }

    // 旋轉監聽介面
    public interface OrientationListener {
        void orientation(int orientation);
    }

    // 設定搖晃監聽
    public void setOnShakeListener(OnShakeListener listener) {
        onShakeListener = listener;
    }
	// 設定旋轉監聽
    public void setOrientationListener(OrientationListener orientationListener) {
        this.orientationListener = orientationListener;
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
    }

    /*
     * 重力感應器感應獲得變化資料
     */
    @Override
    public void onSensorChanged(SensorEvent event) {
        //返回的不是重力感測訊號
        if (Sensor.TYPE_ACCELEROMETER != event.sensor.getType()) {
            return;
        }
        // 檢測時間必須大於間隔時間
        long currentUpdateTime = System.currentTimeMillis();
        long timeInterval = currentUpdateTime - lastUpdateTime;//時間間隔
        if (timeInterval < UPTATE_INTERVAL_TIME) {
            return;
        }
        // 儲存
        lastUpdateTime = currentUpdateTime;
        // 獲得x,y,z座標
        float x = event.values[0];
        float y = event.values[1];
        float z = event.values[2];

        //搖晃監聽
        if (onShakeListener != null) {
            // 獲得x,y,z的變化值
            float deltaX = x - lastX;
            float deltaY = y - lastY;
            float deltaZ = z - lastZ;
            // 將現在的座標變成last座標
            lastX = x;
            lastY = y;
            lastZ = z;
            double speed = Math.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ) / timeInterval * 10000;
            // 達到閥值
            if (speed >= SPEED_SHRESHOLD) {
                onShakeListener.onShake();
            }
        }
        //旋轉監聽
        if (orientationListener != null) {
            //理論上臨界值應為4.5,但是實際效果有所偏差,值為6時效果最佳
            if (x < 6 && x > -6 && y > 6) {
                //豎屏:x∈(-4.5,4.5),y∈(4.5,+∞)
                orientationListener.orientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
            } else if (x < 6 && x > -6 && y < -6) {
                //豎屏反轉:x∈(-4.5,4.5),y∈(-∞,-4.5)
                orientationListener.orientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
            } else if (y > -6 && y < 6 && x > 6) {
                //橫屏:x∈(4.5,+∞),y∈(-4.5,4.5)
                orientationListener.orientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
            } else {
                //橫屏反轉:x∈(-∞,-4.5),y∈(-4.5,4.5)
                orientationListener.orientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
            }
        }
    }

    /**
     * 資源清理,登出監聽
     */
    public void clear() {
        if (sorMgr != null) {
            sorMgr.unregisterListener(this);
            sorMgr = null;
        }
        if (onShakeListener != null) {
            onShakeListener = null;
        }
        if (orientationListener != null) {
            orientationListener = null;
        }
    }
}

相關文章