随笔-311  评论-598  文章-0  trackbacks-0

大多数Android设备有内置的传感器,来测量运动,方向和各种环境条件。这些传感器能提供高精度和准确度的原始数据,如果你想监控设备三维运动或者位置,或者你想监控设备周围的环境变化,是非常有用的。例如,游戏可能跟踪设备重力传感器的数据,来推断复杂的用户首饰和动作,例如倾斜,震动,旋转,或者振幅。同样的,天气应用可能使用设备的温度传感器和湿度传感器的数据来计算和报告结露点,或者旅行应用可能使用磁场传感器和加速度传感器来报告一个指南针方位。 

 

Android平台支持三大类的传感器: 

  • 位移传感器 

这些传感器测量沿三个轴线测量加速度和旋转。这类包含家加速度,重力传感器,陀螺仪,和矢量传感器。 

  • 环境传感器 

这些传感器测量各种环境参数,例如周围的空气温度和压力,光线,和湿度。这类包含气压,光线,和温度传感器。 

  • 位置传感器 

这些传感器测量设备的物理位置。这类包含方向和磁力传感器。 

 

你能访问设备上可用的传感器,并通过使用Android传感器框架获取原始传感器数据。传感器框架提供了一些类和接口,来帮助你执行各种传感器相关的任务。例如,你能使用传感器框架做如下事情: 

  • 确定什么传感器在设备上有效。 

  • 确定当个传感器的功能,例如它的最大射程,厂商,电力需求,和分辨率。 

  • 获取原始数据,并定义你获取传感器数据的最小速率。 

  • 注册和注销传感器事件监听,来监听传感器改变。 

 

这个主题提供了在Android平台上的传感器的概览。它也介绍了传感器框架。 

 

传感器介绍 

——————————————————————————————————————————————————————————— 

Android传感器框架让你访问许多类型的传感器。这些传感器的一些事基于硬件的,一些是基于软件的。基于硬件的传感器是内嵌到手机或者平板中的物理元件,它们通过直接测量指定的环境属性来得到它们的数据,例如加速度,磁场强度,或者角度变化。基于软件的传感器不是物理设备,尽管它们模仿基于硬件的传感器。基于软件的传感器从一个或更多基于硬件的传感器获取它们的数据,并且有时候被称为虚拟传感器或者合成传感器。线性加速度传感器和重力传感器是基于软件传感器的例子。表1总结了Android平台支持的传感器。 

 

很少Android设备有所有类型的传感器。例如,大部分手机和平板有一个加速计和磁场计,但是很少的设备拥有气压或者温度传感器。并且,一个设备可以拥有一个类型不止一个的传感器。例如,设备能有两个重力传感器,每个有不同的范围。 

 

表1.Android平台支持的传感器类型 

传感器 

类型 

描述 

常见用法 

TYPE_ACCELEROMETER 

硬件 

以m/s2测量它设备所有三个物理轴线方向(x,y,和z)加速度,包括重力。 

运动检测(震动,倾角等)。 

TYPE_AMBIENT_TEMPERATURE 

硬件 

以摄氏度测量周围空间的温度,参阅下面的注释。 

检测空气温度。 

TYPE_GRAVITY 

软件或硬件 

以m/s2测量重力, 

运动检测(震动,倾角等)。 

TYPE_GYROSCOPE 

硬件 

以rad/s测量设备三个物理轴线方向(x,y,和z)。旋转速度。 

旋转检测(旋转,转动等)。 

TYPE_LIGHT 

硬件 

以lx测量周围的光线级别。 

控制屏幕的亮度。 

TYPE_LINEAR_ACCELERATION 

软件或硬件 

以m/s2测量设备所有的三个物理轴线方向(x,y,和z)的加速度,包含包含重力。 

检测沿着一个轴向的加速度。 

TYPE_MAGNETIC_FIELD 

硬件 

以uT测量周围的三个物理轴线方向的磁场。 

创建一个罗盘。 

TYPE_ORIENTATION 

软件 

测量设备所有三个物理轴线方向(x,y和x)的旋转角度。当使用Level 3的API的时候,你能通过使用重力传感器和磁场传感器,结合getRotatinMatrix()方法,获取设备的倾斜矩阵和旋转矩阵。 

检测设备的位置。 

TYPE_PRESSURE 

硬件 

以hPa和mbar测量周围空气气压。 

检测空气气压的改变。 

TYPE_PROXIMITY 

硬件 

 

手机在通话时的位置。 

TYPE_RELATIVE_HUMIDITY 

硬件 

一个百分比测量周围相对湿度。 

检测结露点,绝对,和相对湿度。 

TYPE_ROTATION_VECTOR 

软件或硬件 

通过提供设备的三个旋转矢量测量设备方向。 

检测运动和检测旋转。 

TYPE_TEMPERATURE 

硬件 

以摄氏度测量设备的温度。这个传感器在不同设备实现不同,并且这个传感器在API Level 14使用TYPE_AMBIENT_TEMPERATURE替代。 

检测温度。 

传感器框架 

你能访问这些传感器,并通过使用Android传感器框架获取原始数据。Android传感器框架式android.hardware包的一部分,包含下面的类和接口: 

SensorManager 

你能使用这个类来创建一个传感器服务的实例。这个类提供了各种方法类访问和列举传感器,注册和注销传感器事件监听,并获取相应的信息。这个类也提供了几个传感器的常量,用户报告传感器的精确度,设置数据获取速率,和校准传感器。 

Sensor 

你能使用这个类类创建一个指定传感器的实例。这个类提供了各种方法让你确定传感器的功能。 

SensorEvent 

系统使用这个类来创建一个传感器对象,它提供了关于传感器事件的信息。一个传感器事件包含一下信息:原始传感器数据,这类传感器产生的事件,数据的准确性,和事件的时间戳。 

SensorEventListener 

你能使用这个接口来创建两个回掉方法,当传感器的值改变或者当传感器的精度改变的时候,它接受通知(传感器事件)。 

 

在一个典型的应用程序中,你使用这些传感器相关的API来执行两个基本任务: 

  • 识别传感器和传感器的性能 

如果你的应用程序有功能依赖指定的类型的传感器和功能,在运行时识别传感器和传感器的功能是非常有用的。例如,你可能想识别设备上可用的所有传感器,和禁用所有依赖不存在的传感器的应用程序功能。同样,你可能想识别一个指定类型的所有传感器,所以你能选择这个传感器来为你的应用程序实现最佳性能。 

 

  • 检测传感器事件 

检测传感器事件是你如何获取原始传感器数据。传感器事件每次发生的时候,传感器检测到它测量的参数的改变。传感器事件给你提供了四个方面的信息:触发这个事件的传感器的名称,事件的时间戳,事件的精准度,和触发事件的原始传感器数据。 

 

传感器的可用性 

由于传感器可用性设备和设备之间不同,不同的Android版本也不同。这是因为Android的传感器在过去的几个版本都被介绍了。例如,一些传感器在Android1.5(API Level 3)中被介绍,但是一些直到Android2.3(API Level 9)也没有被实现可用。同样的,多个传感器在Android2.3(API Level 9)和Anroid4.0(API Level 14)被介绍。两个传感器被弃用,并且被新的,更好的替代。 

 

表2概括了每个传感器逐个平台分析的可用性。仅仅四个平台被列出是因为这些平台包含传感器的变化。被列出的传感器被弃用仍可在后续的平台可用(提供的传感器在设备上存在),这符合Android向前兼容的策略。 

 

表2.传感器平台的可用性 

传感器 

Android4.0(API Level 14) 

Android2.3(API Level9) 

Android2.2(API Level 8) 

Android1.5(API Level 3) 

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 

Yes 

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(API Level 3)被添加,但是直到Android2.3(API Level 9)也不可用。 

2这个传感器是可用的,但是它被弃用。 

 

识别传感器和传感器的性能 

——————————————————————————————————————————————————————————— 

Android传感器框架提供了许多方法,它使你的运行时确定设备上有哪些传感器变得更容易。这个API也提供了方法,让你确定传感器的性能,例如它的大小范围,它的分辨率,和它要求的电力。 

 

为了识别在设备上的传感器,你首先需要获取传感器服务的索引。为此,你通过调用getSystemService()方法并传递SENSOR_SERVICE参数,创建SensorManager类的一个实例。例如: 

  1. private SensorManager mSensorManager;   
  2. ...   
  3. mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);   
下一步,你能通过调用getSensorList()方法,并使用TYPE_ALL常量获取设备上所有传感器列表。例如: 

  1. List<Sensor> deviceSensors = mSensorManager.getSensorList(Sensor.TYPE_ALL);   
如果你想列出一个指定类型的所有传感器,你应该使用其它的常量替代TYPE_ALL,例如TYPE_GYROSCOPE,TYPE_LINEAR_ACCELERATION,或者TYPE_GRAVITY。 

 

你也可以通过调用getDefaultSensor()方法并传递指定传感器的类型常量,来确定在设备上一个指定类型的传感器是否存在。如果设备上有超过一个指定类型的传感器,一个传感器必须被指定为默认的传感器。如果一个指定类型的传感器默认不存在,这个方法返回null,这意味着设备没有这个类型的传感器。例如,下面的代码用来检测在设备上是否有一个磁场计: 

  1. private SensorManager mSensorManager;   
  2. ...   
  3. mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);   
  4. if (mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD) != null){   
  5.   // Success! There's a magnetometer.   
  6.   }   
  7. else {   
  8.   // Failure! No magnetometer.   
  9.   }   
注意:Android没有要求设备制造商向它们的Android设备内嵌所有类型的传感器,所以设备会有一个广泛的传感器配置。 

 

除了列出设备上的传感器之外,你能使用Sensor类的公共方法来检测个传感器的性能和属性。如果你想你的应用程序,基于设备上可用的不同的传感器或者不同的传感器性能,有不同的行为,这是非常有用的。例如,你可以使用getResolution()和getMaximumRange()方法类获取传感器的测量的分辨率和大小范围。你也能使用getPower()方法类获取传感器的电力需求。 

 

如果你想针对不同厂商的传感器或者不同版本的传感器,