英文原文:http://developer.android.com/guide/topics/sensors/sensors_position.html
版本:Android 4.0 r1 - 08 Mar 2012 0:34
Android 平台提供了两种传感器来检测设备的方位:地磁传感器和方向传感器。 Android 平台还提供了一种传感器,用于检测屏幕表面与其它物体的邻近程度,即被称为距离传感器。 地磁传感器和距离传感器是基于硬件的。大部分手持和桌面设备都内置了地磁传感器。手持设备通常还内置了距离传感器,用于检测与人脸的靠近程度(比如在通话过程中)。 而方向传感器是基于软件的,它的数据来自加速度传感器和地磁传感器。
方位传感器用于确定设备相对地球的物理方位。比如,你可以用地磁传感器和加速度传感器来确定设备相对北极点的方位。 你还可以用方向传感器(或类似的基于传感器的判断方向的方法)来确定设备相对你自己参照系的方位。 方位传感器通常不会用于监测设备的移动情况,诸如震动、倾斜、冲击(详见 运动传感器)。
地磁传感器和方向传感器在 SensorEvent 中返回以多维数组表示的传感器数据。 比如,方向传感器在传感器事件中提供了三个坐标轴方向的地磁强度。 同理,方向传感器还在事件中给出了方位角(侧倾度)、俯仰度和翻滚度。 关于传感器使用的坐标系,请参阅 传感器的坐标系。 距离传感器在事件中给出的是一个值。表 1列出了 Android 平台支持的所有方位传感器。
表 1. Android 平台支持的方位传感器
传感器 | 传感器事件中的数据 | 说明 | 计量单位 |
---|---|---|---|
TYPE_MAGNETIC_FIELD |
SensorEvent.values[0] |
x 轴的地磁强度 | μT |
SensorEvent.values[1] |
y 轴的地磁强度 | ||
SensorEvent.values[2] |
z 轴的地磁强度 | ||
TYPE_ORIENTATION 1 |
SensorEvent.values[0] |
侧倾度(围绕 z 轴的角度) | 度 |
SensorEvent.values[1] |
俯仰度(围绕 x 轴的角度) | ||
SensorEvent.values[2] |
翻滚度(围绕 y 轴的角度) | ||
TYPE_PROXIMITY |
SensorEvent.values[0] |
与物体的距离2 | cm |
方向传感器用于监测设备相对地球的方位(其实是地球磁场)。以下代码展示了如何获取缺省的方向传感器的一个实例:
private SensorManager mSensorManager; private Sensor mSensor; ...mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
方向传感器的数据来自设备的地磁传感器和加速度传感器。利用这两种硬件传感器,方向传感器提供了以下三个方向的数据:
以上定义与航空学上的不同,那里的 X 轴是指飞机的长轴(从机尾至机首)。 并且,由于历史的原因,翻滚度也是以顺时针方向为正(从数学上讲,应该是逆时针方向为正)。
方向传感器的数据是对加速度和地磁传感器的原始数据进行处理之后再报送出来的。 因为处理工作比较繁重,方向传感器的精度和准确度会有所降低(只有在翻滚度为 0 时此传感器的数据才是可靠的)。 因此,方向传感器自 Android 2.2 (API level 8) 开始已经过时了。 作为直接使用方向传感器原始数据的替代方案,我们建议你结合getRotationMatrix() 和 getOrientation() 方法来来计算方向值。你还可以用 remapCoordinateSystem() 方法来把方向值转换为应用程序自定义参照系的坐标。
以下例程展示了如何直接向方向传感器请求方向数据。我们建议你只在设备翻滚度可以忽略时才使用这种方式。
public class SensorActivity extends Activity implements SensorEventListener { private SensorManager mSensorManager; private Sensor mOrientation; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); mOrientation = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION); } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { // 执行一些传感器精度变动后的相关工作 // 必须实现本回调方法的代码 } @Override protected void onResume() { super.onResume(); mSensorManager.registerListener(this, mOrientation, SensorManager.SENSOR_DELAY_NORMAL); } @Override protected void onPause() { super.onPause(); mSensorManager.unregisterListener(this); } @Override public void onSensorChanged(SensorEvent event) { float azimuth_angle = event.values[0]; float pitch_angle = event.values[1]; float roll_angle = event.values[2]; // 利用这些方向角度执行工作 } }
通常你不需要对方向传感器的数据进行任何处理或过滤,当然以应用程序自定义参照系进行坐标转换除外。Accelerometer Play 范例展示了如何把加速度传感器数据转换为其它参照系坐标的过程;方向传感器也可以采用类似的技术来完成转换。
地磁传感器使你能监测地球磁场的变化。以下代码展示了如何获取缺省的地磁传感器的一个实例:
private SensorManager mSensorManager; private Sensor mSensor; ...mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
此传感器提供了三维坐标轴方向上的原始的磁场强度数据(单位μT)。通常,你不需要直接使用此传感器。 取而代之的是,你可以用旋转向量传感器来测量旋转的原始数据,或者联合使用加速度计、地磁传感器、getRotationMatrix() 方法来获取旋转矩阵和倾角矩阵。然后,你可以通过 a href="http://developer.android.com/reference/android/hardware/SensorManager.html#getOrientation(float[], float[])">getOrientation() 和 getInclination() 根据这些矩阵数据得到侧倾度和地磁倾角数据。
距离传感器使你能检测设备距离某物体的远近程度。以下代码展示了如何获取缺省的距离传感器的一个实例:
private SensorManager mSensorManager; private Sensor mSensor; ...mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
距离传感器通常用于确定用户头部与手持设备屏幕表面的距离(比如,用户拨打或接听电话时)。 大部分距离传感器返回的是绝对距离,单位是 cm,但某些传感器只能返回远近程度值。 以下代码展示了距离传感器的使用:
public class SensorActivity extends Activity implements SensorEventListener { private SensorManager mSensorManager; private Sensor mProximity; @Override public final void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // 获取传感器设备的一个实例,并用它获取某个特定的传感器 mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); mProximity = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY); } @Override public final void onAccuracyChanged(Sensor sensor, int accuracy) { // 在这里进行一些传感器精度改变后的处理 } @Override public final void onSensorChanged(SensorEvent event) { float distance = event.values[0]; // 处理当前的传感器数据 } @Override protected void onResume() { // 注册一个传感器侦听器 super.onResume(); mSensorManager.registerListener(this, mProximity, SensorManager.SENSOR_DELAY_NORMAL); } @Override protected void onPause() { // 请在 activity 暂停时确保注销传感器 super.onPause(); mSensorManager.unregisterListener(this); } }