最近几天在开发一款App,其中就用到了一些传感器中的知识,之前对传感器不是很了解,只能对其进行分析学习,现在已经初步成型了,等着其他人的模块,结合起来就OK了。(2013.11.12)
传感器综述
现在手机产商都将传感器加入到手机当中,什么重力、温度、亮度等等,这些设备可以通过Android的感应器框架中提供的接口进行调用。在使用感应器之前需要:确定设备的可用感应器。确定独立感应器的兼容性,如它的最大范围,厂家,电源需求,解析度。请求感应器的原始数据,定义你请求感应器数据的最小量。注册和注销监视感应器变化的感应器监听事件。
传感器就是一种特殊的外设,感受外界的 参数变化,然后反应到手机上面。{参数包括:磁 场、温度、压力、重力加速度、声音。}
按测量物理量分类 :
加速度传感器(accelerometer)
陀螺仪传感器(gyroscope)
环境光照传感器(light)
磁力传感器(magnetic field)
方向传感器(orientation)
压力传感器(pressure)
距离传感器(proximity)
温度传感器(temperature)
按种类分为三大类:
运动传感器:传感器测量加速度的力和旋转力沿x,y,z三个轴的方向。这一类包括加速度计,重力传感器,陀螺仪,和旋转矢量传感器。
环境传感器:传感器测量各种环境参数,如环境空气温度、压力和湿度,光照。这一类包括气压计,光度计,温度计。
位置传感器:传感器测量设备的物理位置。包括定位传感器和磁强计
官方提供的传感器有13个:
我就把它复制于此。
Sensor | Type | Description | Common Uses |
---|---|---|---|
TYPE_ACCELEROMETER | Hardware | Measures the acceleration force in m/s2 that is applied to a device onall three physical axes (x, y, and z), including the force of gravity. | Motion detection (shake, tilt, etc.). |
TYPE_AMBIENT_TEMPERATURE | Hardware | Measures the ambient room temperature in degrees Celsius (°C). See note below. | Monitoring air temperatures. |
TYPE_GRAVITY | Software or Hardware | Measures the force of gravity in m/s2 that is applied to a device on all three physical axes (x, y, z). | Motion detection (shake, tilt, etc.). |
TYPE_GYROSCOPE | Hardware | Measures a device's rate of rotation in rad/s around each of the threephysical axes (x, y, and z). | Rotation detection (spin, turn, etc.). |
TYPE_LIGHT | Hardware | Measures the ambient light level (illumination) in lx. | Controlling screen brightness. |
TYPE_LINEAR_ACCELERATION | Software or Hardware | Measures the acceleration force in m/s2 that isapplied to a device on all three physical axes (x, y, and z), excluding the force of gravity. | Monitoring acceleration along a single axis. |
TYPE_MAGNETIC_FIELD | Hardware | Measures the ambient geomagnetic field for all three physical axes (x, y, z) inμT. | Creating a compass. |
TYPE_ORIENTATION | Software | Measures degrees of rotation that a device makes around all three physical axes (x, y, z). As of API level 3 you can obtain the inclination matrix and rotation matrix for a device by using the gravity sensor and the geomagnetic field sensor in conjunction with the getRotationMatrix() method. | Determining device position. |
TYPE_PRESSURE | Hardware | Measures the ambient air pressure in hPa or mbar. | Monitoring air pressure changes. |
TYPE_PROXIMITY | Hardware | Measures the proximity of an object in cm relative to the view screen of a device. This sensor is typically used to determine whether a handset is being held up to a person's ear. | Phone position during a call. |
TYPE_RELATIVE_HUMIDITY | Hardware | Measures the relative ambient humidity in percent (%). | Monitoring dewpoint, absolute, and relative humidity. |
TYPE_ROTATION_VECTOR | Software or Hardware | Measures the orientation of a device by providing the three elements of the device's rotation vector. | Motion detection and rotation detection. |
TYPE_TEMPERATURE | Hardware | Measures the temperature of the device in degrees Celsius (°C). This sensorimplementation varies across devices andthis sensor was replaced with theTYPE_AMBIENT_TEMPERATURE sensor inAPI Level 14 | Monitoring temperatures. |
他们所对应的常量为:
/**
* A constant describing an accelerometer sensor type. See
* {@link android.hardware.SensorEvent#values SensorEvent.values} for more
* details.
*/
public static final int TYPE_ACCELEROMETER = 1;
/**
* A constant describing a magnetic field sensor type. See
* {@link android.hardware.SensorEvent#values SensorEvent.values} for more
* details.
*/
public static final int TYPE_MAGNETIC_FIELD = 2;
/**
* A constant describing an orientation sensor type. See
* {@link android.hardware.SensorEvent#values SensorEvent.values} for more
* details.
*
* @deprecated use {@link android.hardware.SensorManager#getOrientation
* SensorManager.getOrientation()} instead.
*/
@Deprecated
public static final int TYPE_ORIENTATION = 3;
/** A constant describing a gyroscope sensor type */
public static final int TYPE_GYROSCOPE = 4;
/**
* A constant describing a light sensor type. See
* {@link android.hardware.SensorEvent#values SensorEvent.values} for more
* details.
*/
public static final int TYPE_LIGHT = 5;
/** A constant describing a pressure sensor type */
public static final int TYPE_PRESSURE = 6;
/**
* A constant describing a temperature sensor type
*
* @deprecated use
* {@link android.hardware.Sensor#TYPE_AMBIENT_TEMPERATURE
* Sensor.TYPE_AMBIENT_TEMPERATURE} instead.
*/
@Deprecated
public static final int TYPE_TEMPERATURE = 7;
/**
* A constant describing a proximity sensor type. See
* {@link android.hardware.SensorEvent#values SensorEvent.values} for more
* details.
*/
public static final int TYPE_PROXIMITY = 8;
/**
* A constant describing a gravity sensor type.
* See {@link android.hardware.SensorEvent SensorEvent}
* for more details.
*/
public static final int TYPE_GRAVITY = 9;
/**
* A constant describing a linear acceleration sensor type.
* See {@link android.hardware.SensorEvent SensorEvent}
* for more details.
*/
public static final int TYPE_LINEAR_ACCELERATION = 10;
/**
* A constant describing a rotation vector sensor type.
* See {@link android.hardware.SensorEvent SensorEvent}
* for more details.
*/
public static final int TYPE_ROTATION_VECTOR = 11;
/**
* A constant describing a relative humidity sensor type.
* See {@link android.hardware.SensorEvent SensorEvent}
* for more details.
*/
public static final int TYPE_RELATIVE_HUMIDITY = 12;
/** A constant describing an ambient temperature sensor type */
public static final int TYPE_AMBIENT_TEMPERATURE = 13;
/**
* A constant describing all sensor types.
*/
public static final int TYPE_ALL = -1;
传感器框架
主要涉及到三个类:
SensorEventListener、see SensorEvent、 Sensor、SensorManager
SensorManager你可以使用这个类创建感应器服务的一个实例。这个类提供了各种用于访问、列出、登记、注销感应器的事件监听器方法和获得方向信息的方法。这个类还提供了一些报告感应器的精度,集数据采集速率,和校准感应器的常量。
Sensor你可以使用这个类来创建一个特定的感应器实例。eg:Sensor.TYPE_ACCELEROMETER
SensorEvent系统使用这个类创建一个带一个感应器事件信息的感应器事件对象。感应器事件对象包括以下信息:感应器原始数据,生成的事件,数据的准确性,事件的时间戳类型。
SensorEventListener您可以使用此接口来创建两个接收(感应器事件)通知的回调方法:感应器值的变化事件,感应器的精度变化事件。
识别设别上的感应器
获取设别上的所有传感器
确定设备上的感应器的功能,首先需要得到一个感应器服务的引用。通过调用getSystemService()方法并传递SENSOR_SERVICE参数给它来创建一个SensorManager实例。
private SensorManager mSensorManager; ... mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
再次,通过调用getSensorList()方法和使用的TYPE_ALL常量取得设备上的每个感应器 。
List<Sensor> deviceSensors = mSensorManager.getSensorList(Sensor.TYPE_ALL);
=====================================================================
代码:
SensorManager sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
List<Sensor> deviceSensors = sensorManager
.getSensorList(Sensor.TYPE_ALL);
for (Sensor deviceSensor : deviceSensors) {
Log.d("huang", "===========" + deviceSensor.getType() + "====="
+ deviceSensor.getName());
这是从小米上获取的:
D/huang (20634): ===========1=====LIS3DH 3-axis Accelerometer
D/huang (20634): ===========2=====HMC5883L 3-axis Magnetic Field Sensor
D/huang (20634): ===========3=====HMC5883L Orientation Sensor
D/huang (20634): ===========5=====ISL29028 Light Sensor
D/huang (20634): ===========8=====ISL29028 Proximity Sensor
D/huang (20634): ===========9=====Gravity Sensor
D/huang (20634): ===========10=====Linear Acceleration Sensor
D/huang (20634): ===========11=====Rotation Vector Sensor
Android 并不要求设备制造商内建任何特有的感应器,设备感应器配置可以多样化。
=======================================================================
获取指定的一个传感器
获取一个指定的传感器类型,可以按照以上方式,将其他类型替换Sensor.TYPE_ALL即可,如:
SensorManager sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
List<Sensor> deviceSensors = sensorManager
.getSensorList(Sensor.TYPE_GRAVITY);
还可以使用如下方式:
SensorManager sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
if (sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY) != null) {
// 判断传感设备是否存在,存在.
Sensor gravitySensor = sensorManager
.getDefaultSensor(Sensor.TYPE_GRAVITY);
} else {
// 不存在
}
根据版本和供应商选取传感器
getVendor()传感器供应商
getVersion()传感器版本
private SensorManager mSensorManager; private Sensor mSensor; ... mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); if (mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY) != null){ List<Sensor> gravSensors = mSensorManager.getSensorList(Sensor.TYPE_GRAVITY); for(int i=0; i<gravSensors.size(); i++) { if ((gravSensors.get(i).getVendor().contains("Google Inc.")) && (gravSensors.get(i).getVersion() == 3)){ // Use the version 3 gravity sensor. mSensor = gravSensors.get(i); } } } else{ // Use the accelerometer. if (mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null){ mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); } else{ // Sorry, there are no accelerometers on your device. // You can't play this game. } }
getMinDelay()方法返回0,表示不是流传感器,否则就是。
传感器坐标系
以上面这张图,x轴水平指向右方,y轴垂直指向上方,z轴水平指向胸前。需要注意的是:传感器的坐标系统,不会因手机的屏幕的改变,也就是手机平放还是竖放,坐标系统与这些无关,也与手机的移动无关,坐标系统就是这个样子,不因设备的变化而变化。总而言之,x轴,y轴形成手机平面,z轴垂直手机平面。
需要用到坐标的传感器,有
加速度传感器
重力传感器
陀螺仪
线性加速度传感器
地磁传感器
使用传感器的最佳实践
1、注册传感器
传感器监听器注册后,传感器将继续获取数据并使用电池资源。使用方法unregisterListener(SensorEventListener)
,一般是在onPause方法上使用,如下:
@Override protected void onPause() { super.onPause(); mSensorManager.unregisterListener(this); }
2、莫要使用虚拟机
必须在一个物理设备你的传感器测试代码。
3、不要堵塞onsensorchanged()方法
传感器的数据可以在高速率的变化,这意味着该系统可以经常调用onsensorchanged(sensorevent)方法。作为一个最佳实践,如果你的应用程序需要你做任何的数据过滤或传感器数据还原,你应该做的工作需要在onsensorchanged(sensorevent)方法外。
4、避免使用过时的方法或传感器类型
详见API文档。
5、使用前请确认传感器
使用一个设备上的传感器,有可能这个传感器不存在,不要以为你以为就是以为,有些长按其。
6、仔细选择传感器的延迟
当你注册一个与registerlistener()方法传感器,确保你选择的传送率,是适合您的应用程序或使用案例。传感器可以在很高的利用率提供数据,允许系统发送额外的数据,你不需要浪费系统资源和不使用电池电源。
registerListener(mShakeDetector, mAccelerometer,SensorManager.SENSOR_DELAY_UI);
主要有四个值:
/** get sensor data as fast as possible */
public static final int SENSOR_DELAY_FASTEST = 0;
/** rate suitable for games */
public static final int SENSOR_DELAY_GAME = 1;
/** rate suitable for the user interface */
public static final int SENSOR_DELAY_UI = 2;
/** rate (default) suitable for screen orientation changes */
public static final int SENSOR_DELAY_NORMAL = 3;