目前手机集成了多个不同用途的传感器。最近项目中需要用到加速度传感器和方向传感器,故做一下笔记。
加速度传感器,用于检测手机运动状态。
方向传感器,用于检测手机方向状态。
传感器调用方式:
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;//竖屏
}
}
}
其实检测竖屏横屏有多种方式,但有些方法会存在适配问题,有些机子不管用,传感器基本都适用,灵敏度会有差异而已