Sensor数据的获得
首先要明确的一点就是,获得的传感器数据都是原始数据,即便有一些便利方法,但是也需要获得很多原始数据参数来计算。
因此,很多时候需要自己编写函数来通过这些原始数据计算出自己需要的内容。
比如照片的方向。
照片的方向的问题
在正常竖屏的状况下,CAMERA传感器的角度是90度,在设置里面设置一个orientation值就可以在显示的时候将照片转过来。但是,横屏拍摄以后,照片角度会保持成横屏,不会旋转,这跟我们通常的体验不一样。
我们需要的体验式,不管怎么拍摄,最后照片都应该在竖屏预览的时候正过来。
我们需要针对不同拍摄角度设置不同的orientation值。
传感器数据的获得
Sensors Overview
先要创建一个SensorManager
对象 mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
获得拥有的传感器列表 List<Sensor> sensors = mSensorManager.getSensorList(Sensor.TYPE_ALL);
for(Sensor s:sensors)
{
s.getName();
//传感器名字String s.getType());
//传感器类型int }
注册传感器监听器,监听器就是获得数据的主要部件 mSensorManager.registerListener(Listener,Sensor,Delay);
这个方法有很多重载,这一个是用的比较普遍的一种。
第一个参数是监听器,
第二个参数是Sensor实例,通过mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
获得,这里获得的是加速传感器的实例
第三个参数是获得数据的延迟,例如SensorManager.SENSOR_DELAY_NORMAL
其中延迟从高到低(就是速度从慢到块)分别是NORMER,UI,GAME,FASTEST。
一般状况就用NORMER就可以,已经很快了,需要如游戏输入的操作就用GAME。
注意一点就是,延迟越低越费电。
注册了监听器以后就可以获得数据了,读取数据在监听器里设置。
记得在onPause()
方法里面设置取消注册mSensorManager.unregisterListener(mSensorEventListener);
这样获得更好的续航。程序设计的基本理论有一条就是,不要浪费资源。
建立一个监听器,就是刚才注册进去的那个
SensorEventListener mSensorEventListener =
new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent sensorEvent) {
switch (sensorEvent.sensor.getType()){
case Sensor.TYPE_ACCELEROMETER:
gravity[0] = sensorEvent.values[0];
gravity[1] = sensorEvent.values[1];
gravity[2] = sensorEvent.values[2];
break;
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int i) {
}
};
onSensorChanged(SensorEvent)
在每次传感器数据变化的时候调用并且获得数据,获得的时间间隔就是刚才注册的时候定义的DELAY。
可以为一个SensorManager
注册很多监听器,然后设置不同的DELAY,也可以注册一个监听器,然后在里面判断是哪个传感器的数据。 SensorEvent
可以获得多种数据
SensorEvent
sensorEvent.sensor获得传感器类型,用来判断
SensorEvent.value就是需要的数据
因为每种传感器的数据输出不同,所以这个value也不同,但是大多是一个float
的数组,每个位置对应一个数据,
例如加速传感器有3个数据,对应value[0]
value[1]
value[2]
然后在这个回调方法里面操作这些数据
利用传感器数据计算
这次,我们需要用加速传感器获得方向数据。
加速传感器和重力传感器一般为同一个传感器,
(我使用的NOTE3上,显示两个传感器都有,但是只有加速传感器有数据,重力传感器没有)
官方文档介绍,在手机静止的时候,两个传感器读数一样。其实,根据广义相对论原理,加速度和重力是等效的,无法分辨,所以这一点很好理解。例如你作向上加速度,相当于有一个向下的重力,传感器向下的速读数也会超过9.8
value有3个值,分别对应X,Y,Z轴,
在手机竖放正面朝着自己的时候,X轴向上,Y轴向右,Z轴朝向自己,
每个轴竖直向上的时候,读数就是9.8,竖直向下读数是-9.8,水平读数是0
因此可以得知,通过X,Y轴的数据就可以计算出手机是横排还是竖排了
private int getPhotoOrientation(float x,float y) {
if(Math.abs(x)>Math.abs(y))
{
if(x>0)return 0;
else return 180;
}else {
if(y>0)return 90;
else return 270;
}
}
把这个方法在onSensorChanged()
里面调用一下,就可以获得orientation值。