Android加速度感測器 -- 擡手亮屏
阿新 • • 發佈:2019-01-10
android系統提供以下感測器供應用層使用,具體如下:
// android.hardware.Sensor
TYPE_ACCELEROMETER 1 // 加速度感測器
TYPE_MAGNETIC_FIELD 2 // 磁力感測器
TYPE_ORIENTATION 3 // 方向感測器
TYPE_GYROSCOPE 4 // 陀螺儀感測器
TYPE_LIGHT 5 // 光線感應感測器
TYPE_PRESSURE 6 // 壓力感測器
TYPE_TEMPERATURE 7 // 溫度感測器,目前已被TYPE_AMBIENT_TEMPERATURE替代
TYPE_PROXIMITY 8 // 近距離感測器
SENSOR_TYPE_GRAVITY 9 // 重力感測器
TYPE_LINEAR_ACCELERATION 10 // 線性加速度
TYPE_ROTATION_VECTOR 11 // 旋轉向量
TYPE_RELATIVE_HUMIDITY 12 // 溼度感測器
TYPE_AMBIENT_TEMPERATURE 13 // 溫度感測器
TYPE_MAGNETIC_FIELD_UNCALIBRATED 14 // 未校準磁力感測器
TYPE_GAME_ROTATION_VECTOR 15
TYPE_GYROSCOPE_UNCALIBRATED 16
... ...
- 加速度感測器
加速度感測器又稱之為G-sensor,返回X、Y、Z三軸的加速度值,該數值包含地心引力的影響,單位為m/s^2(米每二次方秒)
將手機平放在桌面,x軸預設為0,y軸預設0,z軸預設9.81
將手機朝下放在桌面,z軸為-9.81
將手機向左傾斜,x軸為正值
將手機向右傾斜,x軸為負值
將手機向上傾斜,y軸為正值
將手機向下傾斜,y軸為負值
- 擡手亮屏
分析擡手動作發現,擡手亮屏需要滿足兩個條件:
1.手機處於拿起移動狀態
2.手機面向人眼處於傾斜狀態
並且觸發這兩個條件的時間間隔約200ms以內
程式碼很簡單,以下是全部程式碼
public class AwakeActivity extends Activity {
private static final String TAG = "ansen";
private SensorManager mSensorManager;
private PowerManager mPowerManager;
private Sensor mGravitySensor;
private PowerManager.WakeLock mWakelock;
private long shakeTime; // 手機觸發拿起動作時間
private long showTime;
private float oldY = 0;
private float subY = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
mPowerManager = (PowerManager) getSystemService(POWER_SERVICE);
mGravitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mWakelock = mPowerManager.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.SCREEN_DIM_WAKE_LOCK, "smartAwake");
mSensorManager.registerListener(mSensorEventListener, mGravitySensor, SensorManager.SENSOR_DELAY_NORMAL);
// mWakelock.acquire();
}
// 加速度感測器監聽
private SensorEventListener mSensorEventListener = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
smartAwake(event);
}
@Override
public void onAccuracyChanged(Sensor arg0, int arg1) {
}
};
// 擡手亮屏邏輯
private void smartAwake(SensorEvent event) {
float[] values = event.values;
float x = values[0];
float y = values[1];
float z = values[2];
Log.i(TAG, "smartAwake x= " + x + " y= " + y + " z=" + z);
subY = y - oldY;
if (Math.abs(x) < 3 && y > 0 && z < 9) {
if(subY > 1){
shakeTime = System.currentTimeMillis();
Log.i(TAG, "1");
}
oldY = y;
}
if (Math.abs(x) < 3 && y > 4 && y < 9 && z > 2 && z < 9) {
showTime = System.currentTimeMillis();
Log.i(TAG, "2");
if (showTime - shakeTime >= 0 && showTime - shakeTime < 200) {
mWakelock.acquire();
mWakelock.release();
// mPowerManager.wakeUp(SystemClock.uptimeMillis(), "smartAwake");
Log.i(TAG, "smartAwake Awake");
}
}
}
@Override
protected void onDestroy() {
super.onDestroy();
mSensorManager.unregisterListener(mSensorEventListener);
}
}
手機水平放置桌面,三軸值約為:X=0,Y=0,Z=9.8,判斷手機是否處於水平狀態觸發的拿起動作程式碼為:
(Math.abs(x) < 3 && y > 0 && z < 9)
判斷手機處於面向人眼傾斜狀態程式碼如下:
(Math.abs(x) < 3 && y > 4 && y < 9 && z > 2 && z < 9)
其中Math.abs(x) < 3 代表手機X軸處於接近水平狀態,Y軸的取值為手機向上傾斜的角度,Z軸同理;這裡的(subY > 1)是避免觸發1和2兩個條件時 手機處於靜止狀態也能點亮螢幕
螢幕喚醒的程式碼為:
mPowerManager.wakeUp(SystemClock.uptimeMillis(), "smartAwake");
由於是@hide api,普通應用無法直接呼叫,因此這裡通過mWakelock.acquire(),獲取喚醒鎖 同樣在滅屏情況下能點亮螢幕.
最後記得新增許可權:
<uses-permission android:name="android.permission.WAKE_LOCK"></uses-permission>
建議手機插上USB的情況下測試斷開USB幾分鐘後加速度感測器可能會停止工作;建議在系統環境下 在Service中執行,並且程式註冊感測器監聽時獲取wakelock,再通過PowerManager的wakeUp來喚醒螢幕來實現擡手亮屏