Android Sensor 理解及架构

Android 6.0 系统支持的传感器多达26种:加速度传感器 (accelerometer)、磁力传感器(magnetic field)、方向传感器(orientation)、陀螺仪(gyroscope)、环境光照传感器(light)、压力传感器(pressure)、温度传感器(temperature)和距离传感器(proximity)等等, Sensor.java 中有相关定义 源码。

Sensor 架构图
Android Sensor 理解及架构_第1张图片
主要包括2个进程,服务端和客户端。 Sensor的整体逻辑非常清晰,一个控制流,一个数据流。

1.常规使用流程ref

1.1 常用API

SensorManager:可以通过这个类去创建一个传感器服务的实例,这个类提供的各种方法可以访问传感器列表、注册或解除注册传感器事件监听、获取方位信息等。
Sensor:用于创建一个特定的传感器实例,这个类提供的方法可以让你决定一个传感器的功能。
SensorEvent:系统会通过这个类创建一个传感器事件对象,提供了一个传感器的事件信息,包含一下内容,原生的传感器数据、触发传感器的事件类型、精确的数据以及事件发生的时间。
SensorEventListener:可以通过这个接口创建两个回调用法来接收传感器的事件通知,比如当传感器的值发生变化时。

1.2 使用方式

第一步:获取SensorManager对象
第二步:获取Sensor对象
第三步:注册Sensor对象
第四步:重写onAccuracyChanged,onSensorChanged这两个方法
第五步:注销Sensor对象

public class SensorActivity extends Activity implements SensorEventListener {
  private SensorManager mSensorManager;
  private Sensor mSensor;
  @Override
  public final void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    //第一步:通过getSystemService获得SensorManager实例对象
    mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
    //第二步:通过SensorManager实例对象获得想要的传感器对象:参数决定获取哪个传感器
    mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
  }
  //第四步:必须重写的两个方法:onAccuracyChanged,onSensorChanged
  /**
   * 传感器精度发生改变的回调接口
   */
  @Override
  public final void onAccuracyChanged(Sensor sensor, int accuracy) {
    //TODO 在传感器精度发生改变时做些操作,accuracy为当前传感器精度
  }
  /**
   * 传感器事件值改变时的回调接口:执行此方法的频率与注册传感器时的频率有关
   */
  @Override
  public final void onSensorChanged(SensorEvent event) {
    // 大部分传感器会返回三个轴方向x,y,x的event值,值的意义因传感器而异
    float x = event.values[0];
    float y = event.values[1];
    float z = event.values[2];
    //TODO 利用获得的三个float传感器值做些操作
  }
  /**
   * 第三步:在获得焦点时注册传感器并让本类实现SensorEventListener接口
   */
  @Override
  protected void onResume() {
    super.onResume();
    /*
     *第一个参数:SensorEventListener接口的实例对象
     *第二个参数:需要注册的传感器实例
     *第三个参数:传感器获取传感器事件event值频率:
   *              SensorManager.SENSOR_DELAY_FASTEST = 0:对应0微秒的更新间隔,最快,1微秒 = 1 % 1000000秒
   *              SensorManager.SENSOR_DELAY_GAME = 1:对应20000微秒的更新间隔,游戏中常用
   *              SensorManager.SENSOR_DELAY_UI = 2:对应60000微秒的更新间隔
   *              SensorManager.SENSOR_DELAY_NORMAL = 3:对应200000微秒的更新间隔
   *              键入自定义的int值x时:对应x微秒的更新间隔
     *
     */
    mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL);
  }
  /**
   * 第五步:在失去焦点时注销传感器
   */
  @Override
  protected void onPause() {
    super.onPause();
    mSensorManager.unregisterListener(this);
  }
}

注意,设备不一定支持你需要的sensor,使用前可以先判断下可用性

private SensorManager mSensorManager;
...
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
if (mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD) != null){
    // Success! There's a magnetometer.
} else {
    // Failure! No magnetometer.
}

//或者
List deviceSensors = mSensorManager.getSensorList(Sensor.TYPE_ALL);

2.常用Sensor解释

2.1 Accelerometer 加速度传感器

加速度传感器又叫G-sensor返回x、y、z三轴的加速度数值
该数值包含地心引力的影响,单位是m/s^2。
将手机平放在桌面上,x轴默认为0,y轴默认0,z轴默认9.81。 将手机朝下放在桌面上,z轴为-9.81。 将手机向左倾斜,x轴为正值。 将手机向右倾斜,x轴为负值。 将手机向上倾斜,y轴为负值。 将手机向下倾斜,y轴为正值。

2.2 Magnetometer 磁力传感器

磁力传感器简称为M-sensor,返回x、y、z三轴的环境磁场数据
该数值的单位是微特斯拉(micro-Tesla),用uT表示。 单位也可以是高斯(Gauss),1Tesla=10000Gauss。
硬件上一般没有独立的磁力传感器,磁力数据由电子罗盘传感器提供(E-compass)。电子罗盘传感器同时提供下文的方向传感器数据

2.3 Orientation 方向传感器

方向传感器简称为O-sensor,返回三轴的角度数据,方向数据的单位是角度。
为了得到精确的角度数据,E-compass(电子罗盘传感器)需要获取G-sensor(加速度传感器)的数据, 经过计算生产O-sensor数据,否则只能获取水平方向的角度。
方向传感器提供三个数据,分别为azimuth、pitch和roll。
azimuth:方位,返回水平时磁北极和Y轴的夹角,范围为0°至360°。 0°=北,90°=东,180°=南,270°=西。
pitch:x轴和水平面的夹角,范围为-180°至180°。 当z轴向y轴转动时,角度为正值。
roll:y轴和水平面的夹角,由于历史原因,范围为-90°至90°。 当x轴向z轴移动时,角度为正值。
电子罗盘在获取正确的数据前需要进行校准,通常可用8字校准法。 8字校准法要求用户使用需要校准的设备在空中做8字晃动, 原则上尽量多的让设备法线方向指向空间的所有8个象限。

2.4 Gyroscope 陀螺仪传感器

陀螺仪传感器叫做Gyro-sensor,返回x、y、z三轴的角速度数据
角速度的单位是radians/second。
根据Nexus S手机实测: 水平逆时针旋转,Z轴为正。 水平逆时针旋转,z轴为负。 向左旋转,y轴为负。 向右旋转,y轴为正。 向上旋转,x轴为负。 向下旋转,x轴为正。

2.5 Gravity 重力传感器

重力传感器简称GV-sensor,输出重力数据

在地球上,重力数值为9.8,单位是m/s^2。 坐标系统与加速度传感器相同。 当设备复位时,重力传感器的输出与加速度传感器相同。

2.6 Linear Acceleration 线性加速度传感器

线性加速度传感器简称LA-sensor。线性加速度传感器是加速度传感器减去重力影响获取的数据。 单位是m/s^2,坐标系统与加速度传感器相同。
加速度传感器、重力传感器和线性加速度传感器的计算公式如下:== 加速度 = 重力 + 线性加速度==

3 坐标系统

手机的自然坐标系

当一个设备被放在其默认的方向上时,X轴是水平指向右的,Y轴是垂直向上的,Z轴是指向屏幕正面之外的,即屏幕背面是Z的负值。
Android Sensor 理解及架构_第2张图片
当设备运动或者旋转的时候,这些坐标轴是不会改变的,即它们是跟随手机的。

即是说,手机坐标系是跟随设备的自然方向的(但是请记住自然方向不一定是竖直,比如平板它的自然方向就很有可能是横向)。

使用这个坐标系的传感器:

  • Acceleration sensor
  • Gravity sensor
  • Gyroscope
  • Linear acceleration sensor
  • Geomagnetic field sensor
    即是说它们的度数显示了在手机的这三个轴上的数字大小。

屏幕旋转

常常要考虑屏幕的旋转,即 屏幕画面相对于自然方向的旋转

于是就需要使用 getRotation() 方法来获取屏幕的旋转值。

这个方法是Display类中的,跟传感器不相关。

这个方法的返回值只对应0,90,180,270四种旋转情况,它说明屏幕显示区域的旋转情况。

世界坐标系

有一些传感器和方法使用相对于世界的坐标系,因为它们返回的数据反映设备相对于地球及真实环境的位置信息。
请见getOrientation() 方法,getRotationMatrix() 方法,Orientation Sensor, 和 Rotation Vector Sensor。
getRotationMatrix()
getRotationMatrix() 方法说明中,定义的世界坐标系如下:
Android Sensor 理解及架构_第3张图片
X轴平行于地面,指向东方。

Y轴平行于地面,指向北极方向。

Z轴垂直于地面,指向天空。

getOrientation()
getOrientation() 方法中所用的坐标系与上面的不同:
Android Sensor 理解及架构_第4张图片
X轴平行于地面,指向西方;
Y轴平行于地面,指向地磁场北极。
Z轴垂直于地面,指向地心。
getOrientation方法的返回值表示:
values[0]: azimuth, rotation around the Z axis.
values[1]: pitch, rotation around the X axis.
values[2]: roll, rotation around the Y axis.
并且这三个角度值都是以弧度做单位,逆时针方向为正。

你可能感兴趣的:(Android开发操作记录)