Android传感器概述.docx
《Android传感器概述.docx》由会员分享,可在线阅读,更多相关《Android传感器概述.docx(14页珍藏版)》请在冰豆网上搜索。
![Android传感器概述.docx](https://file1.bdocx.com/fileroot1/2023-1/8/bce2624f-515b-4cb8-b58c-3a16cf6abc7f/bce2624f-515b-4cb8-b58c-3a16cf6abc7f1.gif)
Android传感器概述
本文译自:
大多数的Android设备都有内置的测量运动、方向、和各种环境条件的传感器。
这些传感器具有提供高精度和准确度的原始数据的能力,可用于监视设备在三维方向的移动和位置、或者监视设备周围环境的变化。
例如,一个游戏可能要从重力传感器中读取轨迹,以便推断出复杂的用户手势和意图,如倾斜、振动、旋转或摆动等。
同样,有关天气的应用程序可能要使用设备的温度传感器和湿度传感器来计算并报告露点;有关旅行的应用程序可能要使用地磁场传感器和加速度传感器来报告罗盘方位。
Android平台支持三种宽泛类别的传感器:
1.运动传感器
这些传感器沿着三轴方向来测量加速度和扭力。
这种类型传感器包括加速度传感器、重力传感器、陀螺仪和选择矢量传感器。
2.环境传感器
这些传感器测量各种环境参数,如周围空气的温度和压力、照度和湿度等。
这种类型传感器包括气压计、光度计、和温度计等。
3.位置传感器
这些传感器用于测量设备的物理位置。
这种类型传感器包括方向传感器和磁力计等。
你能够访问这些设备上有效的传感器,并能通过使用Android传感器框架来获取原始的传感器数据。
该传感器框架提供了几个类和接口来帮助你执行各种传感器相关的任务。
例如:
使用传感器来做以下事情:
1.判断设备上有哪些传感器可用;
2.判断个别传感器的能力,如它们的最大范围、制造商、电力需求和辨识率;
3.获取原始传感器数据,并定义获取传感器数据的最小比率;
4.注册和解除注册用于监听传感器变化的事件监听器。
本文提供了Android平台上可用的传感器的概述,同时也提供了对传感器框架的介绍,详细请参照后续文章。
传感器介绍
Android传感器框架能够让你访问多种类型的传感器。
其中某些传感器是基于硬件的,有些传感器是基于软件的。
基于硬件的传感器是内置与手持或平板设备中的物理组件。
它们通过直接测量特定的环境属性来获取数据,如加速度、磁场强或角度的变化等。
基于软件的传感器不是物理设备,尽管它们模拟基于硬件的传感器。
基于软件的传感器从一个或多个有时被叫做虚拟传感器或合成传感器的基于硬件的传感器来获取数据。
线性加速度传感器和重力传感器是基于硬件的传感器的实例。
表1概要的介绍了Android平台所支持的传感器。
很少有Android设备支持所有类型的传感器。
例如,大多数手持设备和平板设备都有一个加速仪和一个磁力仪,但是很少有气压计和温度计的设备。
一个设备上也能够有多个同一给定类型的传感器。
例如,一个有设备能够有两个重力传感器,每个都有不同测量范围。
表1.Android平台所支持的传感器类型
传感器
类型
介绍
常用场景
TYPE_ACCELEROMETER
Harderware
以m/s2为单位测量应用于设备三轴(X、Y、Z)的加速力,包括重力
运动检测(振动、倾斜等)
TYPE_AMBIENT_TEMPERATURE
Harderware
以摄氏度(°C)为单位测量周围温度。
监测空气温度
TYPE_GRAVITY
Softwareor
Harderware
以m/s2为单位测量应用于设备三轴(X、Y、Z)的重力。
运动检测(振动、倾斜等)
TYPE_GYROSCOPE
Hardware
以弧度/秒(rad/s)为单位,测量设备围绕三个物理轴(X、Y、Z)的旋转率
旋转检测(旋转、翻转等)
TYPE_LIGHT
Hareware
以lx为单位,测量周围的亮度等级(照度)
控制屏幕的亮度
TYPE_LINEAR_ACCELERATION
Softwareor
Harderware
以m/s2为单位测量应用于设备三个物理轴(X、Y、Z)的加速力,重力除外
检测一个单独的物理轴的加速度。
TYPE_MAGNETIC_FIELD
Hardware
以μT为单位,测量设备周围三个物理轴(x,y,z)的磁场。
创建一个罗盘
TYPE_ORIENTATION
Software
测量设备围绕三个物理轴(x,y,z)的旋转角度。
在APILevel3以后,你能够通使用重力传感器和磁场传感器跟getRotationMatrix()方法相结合来获取倾斜矩阵和旋转矩阵。
判断设备的位置
TYPE_PRESSURE
Hardware
以hPa或mBar为单位来测量周围空气的压力
检测空气压力的变化
TYPE_PROXIMITY
Hardware
以cm为单位,测量一个对象相对与设备屏幕的距离。
这个传感器通常用于判断手持设备是否被举到了一个人的耳朵附近。
通话期间的电话位置。
TYPE_RELATIVE_HUMIDITY
Hardware
以百分比(%)为单位测量周围的相对湿度
监测露点,绝对和相对的湿度。
TYPE_ROTATION_VECTOR
Softwareor
Harderware
通过提供设备旋转矢量的三个要素来测量设备的方向
运动监测和旋转监测。
TYPE_TEMPERATURE
Hardware
以摄氏度((°C)为单位来测量设备的温度。
这个传感器在各种不同设备中被实现,并且在APILevel14中被用于替换TYPE_AMBIENT_TEMPERATURE传感器
监测温度
传感器框架
通过使用Android框架,你能够访问这些传感器,并获取原始的传感器数据。
传感器框架是android.hardware包的一部分,并且包括以下类和接口:
1.SensorManager
使用这个类来创建一个传感器服务的实例。
这个类提供了各种用于访问和监听传感器的方法,它还提供了几个传感器常量,用于报告传感器的精度、设置数据获取的速率以及校准传感器等。
2.Sensor
使用这个类来创建一个特殊传感器的实例。
它提供了判断传感器能力的各种方法。
3.SensorEvent
系统使用这个类来创建一个传感器事件对象,他提供了相关传感器事件的信息。
一个传感器事件对象包含以下信息:
A.原始传感器数据;
B.产生事件的传感器的类型;
C.数据的精度;
D.事件的时间戳。
4.SensorEventListener
使用这个接口来创建两个回调方法,这两个方法在传感器值变化时或精度变化时,接收通知(传感器事件)。
在典型的应用程序中,你使用传感器相关的API来执行两项基本任务:
1.识别传感器及传感器能力
在运行时识别传感器和传感器能力,对于判断你的应用程序是否有功能依赖特殊的传感器类型和能力是有益的。
例如,你可能想要识别当前设备上的所有传感器,并且要禁用所有的依赖传感器所不具备的能力的功能。
同样,你可能想要识别所有的给定类型的传感器,以便你能够选择适合你的应用程序需要的传感器。
2.监视传感器事件
监视传感器事件是获取原始传感器数据的方式。
传感器事件是在每次检测到它的测量参数发生变化时发生。
传感器事件提供了4种信息:
A.触发事件的传感器的名称;
B.事件的时间戳;
C.事件的精度;
D.触发事件的原始传感器数据。
传感器的可用性
传感器的可用性不但在不同硬件之间有变化,而且不同的Android版本之间也可能有变化。
这是因为Android传感器的引入需要有几个平台Release的过程。
例如,某些传感器在Android1.5(APILevel3)中被引入,但有些并没有被实现,直到Android2.3(APILevel9)时才可用。
同样,一些在Android2.3(APILevel9)和Android4.0(APILevel14)被引入的传感器,其中有两个已经被弃用,并用更新、更好的传感器来替代。
表2概要的说明了每个传感器在各个基本平台上的可用性。
这里只列出了4个平台,因为它们是涉及到传感器变化的平台。
列出的那些被弃用的传感器,依然在后续的平台上有效(在提供该传感器的设备上),这是Android的向后兼容性策略。
表2.传感器的平台可用性
传感器
Android4.0
(APILevel14)
Andoroid2.3
(APILevel9)
Android2.2
(APILevel8)
Android1.5
(APILevel3)
TYPE_ACCELEROMETER
Yes
Yes
Yes
Yes
TYPE_AMBIENT_TEMPERATURE
Yes
n/a
n/a
n/a
TYPE_GRAVITY
Yes
Yes
n/a
n/a
TYPE_GYROSCOPE
Yes
Yes
n/a1
n/a1
TYPE_LIGHT
Yes
Yes
Yes
Yes
TYPE_LINEAR_ACCELERATION
Yes
Yes
n/a
n/a
TYPE_MAGNETIC_FIELD
Yes
Yes
Yes
Yes
TYPE_ORIENTATION
Yes2
Yes2
Yes2
Yes2
TYPE_PRESSURE
Yes
Yes
n/a1
n/a1
TYPE_PROXIMITY
Yes
Yes
Yes
Yes
TYPE_RELATIVE_HUMIDITY
Yes
n/a
n/a
n/a
TYPE_ROTATION_VECTOR
Yes
Yes
n/a
n/a
TYPE_TEMPERATURE
Yes2
Yes
Yes
Yes
1这种传感器类型在Android1.5(APILevel3)中被添加,但知道Android2.3(APILevel9)以后才可以使用;
2这种传感器是有效的,但已经被弃用了。
识别传感器和传感器能力
Android传感器框架提供了几个方法,这些方法让你在运行时能够容易判断设备上的传感器。
API还提供了几个让你判断每个传感器能力的方法,如最大范围、识别率、功率需求等。
要识别设备上的传感器,首先需要获得一个引用传感器服务。
通过调用getSystemService()方法并给它传递SENSOR_SERVICE参数来创建一个SensorManager类的实例,可以获得一个传感器服务。
例如:
privateSensorManagermSensorManager;
...
mSensorManager=(SensorManager)getSystemService(Context.SENSOR_SERVICE);
接下来,调用带有TYPE_ALL常量的getSensorList()方法能够获得设备上的所有传感器列表。
例如:
ListdeviceSensors=mSensorManager.getSensorList(Sensor.TYPE_ALL);
如果想要列出给定类型的传感器,你能够使用另外的常量来代替TYPE_ALL,如TYPE_GYROSCOPE、TYPE_LINEAR_ACCELERATION或TYPE_GRAVITY。
通过使用getDefaultSensor方法,你也能够判断设备上是否存在指定类型的传感器。
如果设备上有多个给定类型的传感器,就要保证有一个必须是默认的传感器。
如果给定的传感器类型不存在默认的传感器,该方法调用会返回null,这就意味着设备上没有这种类型的传感器。
例如,以下代码检查设备上是否存在磁力计:
privateSensorManagermSensorManager;
...
mSensorManager=(SensorManager)getSystemService(Context.SENSOR_SERVICE);
if(mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD)!
=null){
//Success!
There'samagnetometer.
}
else{
//Failure!
Nomagnetometer.
}
注意:
Android不要求制造商在他们的Android设备中内容任何特殊类型的传感器,因此设备能够有广泛的传感器配置。
除了列出设备上的传感器,你能够使用Sensor类的Public方法来判断个别传感器的能力和属性。
如果想要你的应用程序有别于基本传感器或设备上可用传感器的行为,这是非常有用的。
例如,使用getResolution和getMaximumRange()方法来获取传感器的识别率和最大的测量范围,也能够使用getPower方法来获取传感器器的功率需求。
如果你想要对不同制造商的传感器或不同版本的传感器来优化你应用程序,有两个public方法是特别有用的。
例如,如果你的应用程序需要监视用户诸如摆动和振动这样的手势,你能够创建一组针对有比较新的矢量重力传感器的设备数据优化过滤规则,和另一组针对没有重力传感器且只有加速度传感器的设备数据优化过滤规则。
下列代码示例演示了如何使用getVendor()和getVersion()方法来做这件事。
在这个示例中,我们查找GoogleInc中列出的有版本数字3的重力传感器。
如果设备上不存在该传感器,我们试着使用加速度传感器。
privateSensorManagermSensorManager;
privateSensormSensor;
...
mSensorManager=(SensorManager)getSystemService(Context.SENSOR_SERVICE);
if(mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY)!
=null){
ListgravSensors=mSensorManager.getSensorList(Sensor.TYPE_GRAVITY);
for(inti=0;iif((gravSensors.get(i).getVendor().contains("GoogleInc."))&&
(gravSensors.get(i).getVersion()==3)){
//Usetheversion3gravitysensor.
mSensor=gravSensors.get(i);
}
}
}
else{
//Usetheaccelerometer.
if(mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)!
=null){
mSensor=mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
}
else{
//Sorry,therearenoaccelerometersonyourdevice.
//Youcan'tplaythisgame.
}
}
另一个有用的方法是getMinDelay(),它返回传感器感知数据的最小时间间隔(以毫秒为单位)。
getMinDelay()方法返回非零值的传感器是流传感器。
流传感器定期的感知数据,并在Android2.3(APILevel9)被引入。
如果调用getMinDelay()方法时返回0,这意味着传感器不是流传感器,因为它只在变化的时候报告它感知到的数据。
getMinDelay()方法有用是因为它会让你判断传感器能够获取数据的最大的频率。
如果在你的应用程序中某个功能需要高精度频率或流传感器,就能够使用这个方法来判断一个传感器是否满足这些要求,然后在你的应用程序中启用或禁止相关功能。
警告:
传感器最大的数据采集频率不一定是传感器框架把传感器数据发送给你的应用程序的频率。
传感器框架通过传感器事件来报告数据,并且有几个因素会影响应用程序接收传感器事件的频率。
监视传感器事件
要监视原始的传感器数据,你需要实现两个通过SensorEventListener接口暴露的回调方法:
onAccuracyChanged()和onSensorChanged()。
Android系统在任何发生下列事情的时候都会调用这两个方法:
1.传感器精度的改变:
这种情况中,系统会调用onAccuracyChanged()方法,它提供了你要引用的发生精度变化的Sensor对象。
精度使用以下四个状态常量之一来代表的:
SENSOR_STATUS_ACCURACY_LOW
SENSOR_STATUS_ACCURACY_MEDIUM
SENSOR_STATUS_ACCURACY_HIGH
SENSOR_STATUS_UNRELIABLE
2.传感器报告新的值:
这种情况中,系统会调用onSensorChanged()方法,它提供了一个SensorEvent对象。
SensorEvent对象包含了有关新的传感器数据的信息,包括:
数据的精度、产生数据的传感器、产生数据时的时间戳、以及传感器记录的新的数据。
下列代码显示了如何使用onSensorChanged()方法来监视来自亮度传感器的数据。
这个例子在一个TextView中显示原始的传感器数据:
publicclassSensorActivityextendsActivityimplementsSensorEventListener{
privateSensorManagermSensorManager;
privateSensormLight;
@Override
publicfinalvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mSensorManager=(SensorManager)getSystemService(Context.SENSOR_SERVICE);
mLight=mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
}
@Override
publicfinalvoidonAccuracyChanged(Sensorsensor,intaccuracy){
//Dosomethinghereifsensoraccuracychanges.
}
@Override
publicfinalvoidonSensorChanged(SensorEventevent){
//Thelightsensorreturnsasinglevalue.
//Manysensorsreturn3values,oneforeachaxis.
floatlux=event.values[0];
//Dosomethingwiththissensorvalue.
}
@Override
protectedvoidonResume(){
super.onResume();
mSensorManager.registerListener(this,mLight,SensorManager.SENSOR_DELAY_NORMAL);
}
@Override
protectedvoidonPause(){
super.onPause();
mSensorManager.unregisterListener(this);
}
}
在这个例子中,在调用registerListener()方法时,指定了默认的数据延迟(SENSOR_DELAY_NORMAL)。
数据延迟(或采样率)控制着传感器事件通过onSensorChanged()回调方法发送给你的应用程序的时间间隔。
默认的数据延迟适用于监视典型的屏幕方向的变化,它所使用的时间延迟是200,000毫秒。
你能够指定其他的数据延迟类型,如SENSOR_DELAY_GAME(20,000毫秒延迟)、SENSOR_DELAY_UI(60,000毫秒延迟)、或者是SENSOR_DELAY_FASTEST(0毫秒延迟)。
Android3.0(APILevel11)以后,你也能够使用一个绝对值(以毫秒的形式)来指定延迟。
你所指定的延迟只是建议性的延迟。
Android系统和其他应用程序都能够修改这个延迟。
作为最好的实践,你应该指定你所需要的最大延迟,因为系统通常会使用比你指定的要小的延迟(也就是说,你应该选择你的应用所需要的最低的采样率)。
使用较大的延迟会降低处理器的负载,同时也因此降低了电量的损耗。
有没有公开的方法用于判断传感器框架把传感器事件发送给你的应用程序的频率;但是,你能够使用前后两个传感器事件的时间戳来计算采样率。
一旦你设置了采样率(延迟)就不要改变。
如果因为某些原因需要改变,那么就必须先注销然后在重新注册传感器监听器。
在这个例子中还要重点关注的是:
使用onResume()和onPause()回调方法来注册和注销传感器监听事件。
作为最好的实践,你始终应该在不需要的时候禁用传感器,尤其是在Activity被挂起的时候。
如果不这样做,因为有些传感器有很大的电量需求,因此会很快的消耗掉电池电量。
在屏幕关闭的时候,系统不会自动的禁用传感器。
处理不同的传感器器配置
Android不给设备指定标准的传感器配置,这就意味着制造商能够把任何他们想要的传感器配置包含到他们的Android设备中。
因此,设备能够包含配置广泛的各种传感器。
例如,摩托罗拉的Xoom有一个压力传感器,但是三星的NexusS却没有。
同样Xoom和NexusS都有陀螺仪,但是HTC的NexusOne却没有。
如果你的应用程序依赖特殊类型的传感器,就必须确保传感器存在于设备上,以保证你的应用程序能够成功的运行。
有两种方法来确定给定的传感器是否存在于设备上:
1.在运行时检测传感器,并根据检测结果来启用或禁用应用程序相关的功能;
2.使用GooglePlay来过滤目标设备上是否有指定的传感器配置。
在运行时检测传感器
如果你的应用程序使用的是一种特殊的传感器类型,但是不想依赖它,你能够使用传感器框架在运行时来检测该传感器,然后决定禁止或启用应用程序对应的功能。
例如,一个导航应用程序可能要使用温度传感器、压力传感器、GPS传感器和地磁场传感器来显示温度、气压、位置和罗盘方位。
如果设备没有压力传感器,你能够使用传感器框架在运行时来检测压力传感器的存在性,然后禁用显示压力的应用程序的UI部分。
例如,下列代码用来检查设备上是否有压力传感器:
privateSensorManagermSensorManager;
...
mSensorManager=(SensorManager)getSystemService(Context.SENSOR_SERVICE);
if(mSensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE)!
=null){
//Success!
There's