Android開發之感測器(加速度感測器、方向感測器)
阿新 • • 發佈:2019-02-03
目前手機集成了多個不同用途的感測器。最近專案中需要用到加速度感測器和方向感測器,故做一下筆記。
加速度感測器,用於檢測手機運動狀態。
方向感測器,用於檢測手機方向狀態。
感測器呼叫方式:
1、初始化
SensorManager manager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); //指定監聽的感測器型別 //all為全部,ACCELEROMETER為加速度,ORIENTATION為方向 Sensor orientsensor = manager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
2、註冊監聽
//方式1:當前activity實現SensorEventListener介面
manager.registerListener(Mainactivity.this, sensor, SensorManager.SENSOR_DELAY_NORMAL);
//方式2:自定義感測器監聽器,實現SensorEventListener
sensorManager.registerListener(MycustomSensorListener, sensor, SensorManager.SENSOR_DELAY_NORMAL);
3、實現OnSensorChange方法,獲取 x,y,z三軸的座標。
if (event.sensor.getType() == Sensor.TYPE_ORIENTATION){
float x = event.values[0];
float y = event.values[1];
float z = event.values[2];
}
4、使用完畢,記得登出
if (null != manager && null != sensor ){ manager.unregisterListener(MainActivity.this,sensor); }
需要說明的是,不同手機的感測器靈敏度不同,而且感測器的呼叫是不間斷的,所以使結果更準確,最好是取一段時間內的感測器變化,為適配大多數手機,需要設定一個閾值或者範圍。
例如呼叫加速度感測器,檢測手機搖一搖:
//檢測的時間間隔
private static final int UPDATE_INTERVAL = 100;
private long mLastUpdateTime;
private float mLastX, mLastY, mLastZ;
//搖晃檢測閾值,決定了對搖晃的敏感程度,越小越敏感
private int shakeThreshold = 1200;
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
long currentTime = System.currentTimeMillis();
long diffTime = currentTime - mLastUpdateTime;
if (diffTime < UPDATE_INTERVAL) {
return;
}
mLastUpdateTime = currentTime;
float x = event.values[0];
float y = event.values[1];
float z = event.values[2];
float deltaX = x - mLastX;
float deltaY = y - mLastY;
float deltaZ = z - mLastZ;
mLastX = x;
mLastY = y;
mLastZ = z;
float delta = (float) (Math.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ) / diffTime * 10000);
// 當檢測到一個搖晃(加速度的差值大於指定閾值)
if (delta > shakeThreshold ) {
dosomething();
}
}
}
關於方向感測器座標軸
z是指向地心的方位角,x軸是仰俯角(由靜止狀態開始前後反轉),y軸是翻轉角(由靜止狀態開始左右反轉)。
方向感測器結合地磁感測器可以實現指南針功能。單獨使用,可以檢測手機的方向,例如豎屏橫屏狀態。
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ORIENTATION){
long currentTime = System.currentTimeMillis();
long diffTime = currentTime - mLastUpdateTime;
if (diffTime < UPDATE_INTERVAL) {
return;
}
mLastUpdateTime = currentTime;
float x = event.values[0];
if ( 260 < x && x < 290 ){
screenStatus = 1;//右橫屏
}else if (80 < x && x < 110){
screenStatus = 2;//左橫屏
}else {
screenStatus = 0;//豎屏
}
}
}
其實檢測豎屏橫屏有多種方式,但有些方法會存在適配問題,有些機子不管用,感測器基本都適用,靈敏度會有差異而已