大多数 Android 设备都内置了传感器,这些传感器可以测量动作、方向 和各种环境条件的变化。这些传感器能够提供具有高要求的原始数据, 精确度和精确度,在监控三维设备运动或 定位,或者您想要监控设备附近环境环境中的变化。例如, 游戏可能会跟踪设备重力传感器的读数,以推断复杂的用户手势 以及各种动作,例如倾斜、摇晃、旋转或挥动。同样,天气应用程序可能使用 设备的温度传感器和湿度传感器,以计算和报告露点或行程 应用可以使用地磁场传感器和加速度计来报告罗盘 方位。
请参阅以下相关资源:
- 传感器
- 移动传感器
- 排名 传感器
- 环境 传感器
- <ph type="x-smartling-placeholder"></ph> API 演示 (OS - RotationVectorDemo)
Android 平台支持三大类传感器:
- 移动传感器
这类传感器测量三个轴向上的加速力和旋转力。这个 类别包括加速度计、重力传感器、陀螺仪和旋转矢量传感器 传感器。
- 环境传感器
这些传感器测量各种环境参数,例如环境气温 以及压力、照度和湿度。这个类别包括气压计、光度计和 温度计。
- 位置传感器
这类传感器测量设备的物理位置。此类别包括: 方向传感器和磁力计。
您可以使用 Android 设备访问设备上的传感器并获取原始传感器数据 传感器框架。传感器框架提供了多个类和接口,可帮助您执行多种 各种与传感器相关的任务。例如,您可以使用传感器框架执行以下操作:
- 确定设备上有哪些传感器。
- 确定单个传感器的功能,例如最大范围、制造商、功率 要求和解决方案
- 获取原始传感器数据并定义获取传感器数据的最低频率。
- 注册和取消注册用于监控传感器变化的传感器事件监听器。
本主题概述了 Android 平台上可用的传感器。 以及传感器框架。
传感器简介
利用 Android 传感器框架,您可以访问多种类型的传感器。其中一些传感器 基于硬件,有些基于软件。基于硬件的传感器是构建的物理组件 手机或平板设备他们通过直接测量特定环境状况来推导出数据 例如加速度、地磁场强度或角度变化。基于软件 虽然它们模拟了基于硬件的传感器,但它们不是物理设备。基于软件的传感器 从一个或多个基于硬件的传感器获取数据,有时也称为虚拟传感器, 传感器或合成传感器例如,线性加速度传感器和重力传感器 基于软件的传感器。表 1 总结了 Android 支持的传感器 平台。
很少有 Android 设备拥有所有类型的传感器。例如,大多数手机设备和 带有加速度计和磁力计的平板电脑,但配备 气压计或温度计此外,一个设备可以有多个特定类型的传感器。对于 例如,一个设备可以有两个重力传感器,每个重力传感器的范围各不相同。
传感器 | 类型 | 说明 | 常见用途 |
---|---|---|---|
TYPE_ACCELEROMETER |
硬件 | 测量施加到设备的加速力(以 m/s2 为单位) 所有三个物理轴(x、y 和 z),包括重力。 | 移动侦测(摇晃、倾斜等)。 |
TYPE_AMBIENT_TEMPERATURE |
硬件 | 以摄氏度 (°C) 为单位测量环境室温。请参见下面的备注。 | 监测气温。 |
TYPE_GRAVITY |
软件或硬件 | 测量施加到所有设备的重力(以 m/s2 为单位) 三条物理轴(x、y、z)。 | 移动侦测(摇晃、倾斜等)。 |
TYPE_GYROSCOPE |
硬件 | 测量设备围绕三维空间的旋转速率(以 rad/s 为单位) 物理轴 (x、y 和 z)。 | 旋转检测(旋转、转动等)。 |
TYPE_LIGHT |
硬件 | 测量环境光级(照度),以 lx 为单位。 | 控制屏幕亮度。 |
TYPE_LINEAR_ACCELERATION |
软件或硬件 | 测量加速度,以 m/s2 为单位, 应用至某台设备上 所有三个物理轴(x、y 和 z),不包括重力。 | 监测单个轴向上的加速度。 |
TYPE_MAGNETIC_FIELD |
硬件 | 测量所有三个物理轴(x、y、z)的环境地磁场 μT。 | 创建罗盘。 |
TYPE_ORIENTATION |
软件 | 测量设备围绕所有三个物理轴(x、y、z)进行的旋转度数。
从 API 级别 3 开始,您可以获取
将重力传感器和地磁场传感器与
getRotationMatrix()
方法。 |
确定设备位置。 |
TYPE_PRESSURE |
硬件 | 测量环境气压,以 hPa 或 mbar 为单位。 | 监测气压变化。 |
TYPE_PROXIMITY |
硬件 | 测量物体相对于视图屏幕的距离(以厘米为单位) 设备。该传感器通常用于确定手机是否被举到 | 通话过程中手机的位置。 |
TYPE_RELATIVE_HUMIDITY |
硬件 | 测量环境的相对湿度,以百分比 (%) 表示。 | 监测露点、绝对湿度和相对湿度。 |
TYPE_ROTATION_VECTOR |
软件或硬件 | 通过提供设备方向的三个元素来测量设备的屏幕方向, 旋转矢量。 | 移动侦测和旋转检测。 |
TYPE_TEMPERATURE |
硬件 | 测量设备的温度,以摄氏度 (°C) 为单位。此传感器
实现方式因设备和设备而异,
此传感器已替换为以下国家/地区中的 TYPE_AMBIENT_TEMPERATURE 传感器:
API 级别 14 |
监测温度。 |
传感器框架
您可以使用 Android 传感器框架访问这些传感器并获取传感器原始数据。
传感器框架是 android.hardware
软件包的一部分,其中包含以下内容
类和接口:
SensorManager
- 您可以使用这个类来创建传感器服务的实例。这个类提供了 用于访问和列出传感器、注册和取消注册传感器事件的各种方法 监听器以及获取屏幕方向信息。该类还提供了几个传感器常量, 用于报告传感器准确性、设置数据采集率和校准传感器。
Sensor
- 您可以使用这个类来创建特定传感器的实例。这个类提供各种 方法,用于确定传感器的特性。
SensorEvent
- 系统使用此类来创建传感器事件对象,该对象会提供 传感器事件。传感器事件对象包含以下信息:原始传感器数据、 生成该事件的传感器类型、数据的准确性和 事件。
SensorEventListener
- 您可以使用此接口创建两个回调方法,用于接收通知(传感器 事件)。
在典型的应用中,您可以使用这些与传感器相关的 API 来执行两个基本任务:
- 识别传感器和传感器功能
如果您的应用具有 依赖特定传感器类型或功能的功能。例如,您可能希望 识别设备上的所有传感器,并停用所有应用功能 依赖不存在的传感器的应用。同样,您可能需要找出 以便您可以选择性能最佳的传感器实现 。
- 监控传感器事件
您可以通过监控传感器事件来获取原始传感器数据。每次都会发生传感器事件 传感器检测到它所测量的参数的变化。传感器事件为您提供 包含四条信息:触发事件的传感器的名称、 事件的时间戳、事件的准确度以及触发的原始传感器数据 事件。
传感器可用性
虽然传感器可用性因设备而异,但也可能因 Android 设备而异 版本。这是因为 Android 传感器是在数个研究阶段引入的 平台版本例如,许多传感器是在 Android 1.5(API 级别 3)中引入的,但有些 未实现,且在 Android 2.3(API 级别 9)之前无法使用。同样, Android 2.3(API 级别 9)和 Android 4.0(API 级别 14)中引入了多个传感器。二 已废弃,取而代之的是更新、更好的传感器。
表 2 总结了每个传感器在不同平台上的可用性。只有四个 之所以列出这些平台,是因为这些平台涉及到传感器变更。传感器 被列为已弃用的平台在后续平台上仍然可用(前提是 传感器),这符合 Android 的向前兼容性政策。
传感器 | Android 4.0 (API 级别 14) |
Android 2.3 (API 级别 9) |
Android 2.2 (API 级别 8) |
Android 1.5 (API 级别 3) |
---|---|---|---|---|
TYPE_ACCELEROMETER |
是 | 是 | 是 | 是 |
TYPE_AMBIENT_TEMPERATURE |
可用 | 不可用 | 不可用 | 不适用 |
TYPE_GRAVITY |
是 | 可用 | 不可用 | 不适用 |
TYPE_GYROSCOPE |
是 | 可用 | 不可用1 | 不可用1 |
TYPE_LIGHT |
是 | 是 | 是 | 是 |
TYPE_LINEAR_ACCELERATION |
是 | 可用 | 不可用 | 不适用 |
TYPE_MAGNETIC_FIELD |
是 | 是 | 是 | 是 |
TYPE_ORIENTATION |
可用2 | 可用2 | 可用2 | 可用 |
TYPE_PRESSURE |
是 | 可用 | 不可用1 | 不可用1 |
TYPE_PROXIMITY |
是 | 是 | 是 | 是 |
TYPE_RELATIVE_HUMIDITY |
可用 | 不可用 | 不可用 | 不适用 |
TYPE_ROTATION_VECTOR |
是 | 可用 | 不可用 | 不适用 |
TYPE_TEMPERATURE |
可用2 | 可用 | 是 | 是 |
1 此传感器类型是在 Android 1.5(API 级别)中添加的 3)、 但直到 Android 2.3(API 级别 9)才可供使用。
2 此传感器可用,但已 已弃用。
识别传感器和传感器特性
Android 传感器框架提供了多种方法,可以让您轻松确定 运行时。API 还提供了一些方法,让您能够确定 每个传感器的功能,例如最大范围、分辨率和功率 要求。
要识别设备上的传感器,您首先需要获取对传感器的引用
服务。为此,您可以通过以下方法创建 SensorManager
类的实例:
调用 getSystemService()
方法并传递
。SENSOR_SERVICE
例如:
Kotlin
private lateinit var sensorManager: SensorManager ... sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
Java
private SensorManager sensorManager; ... sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
接下来,您可以调用
getSensorList()
方法并使用 TYPE_ALL
常量。例如:
Kotlin
val deviceSensors: List<Sensor> = sensorManager.getSensorList(Sensor.TYPE_ALL)
Java
List<Sensor> deviceSensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
如果您想列出给定类型的所有传感器,可以使用另一个常量来代替
TYPE_ALL
,例如 TYPE_GYROSCOPE
,
TYPE_LINEAR_ACCELERATION
或
TYPE_GRAVITY
。
您还可以使用 getDefaultSensor()
方法并传入类型来确定设备上是否存在特定类型的传感器
常量。如果设备有多个特定类型的传感器,则
必须指定为默认传感器。如果指定传感器不存在默认传感器,
某种类型的传感器,该方法调用会返回 null,这意味着设备没有该类型的
传感器。例如,以下代码会检查设备上是否有磁力计:
Kotlin
private lateinit var sensorManager: SensorManager ... sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager if (sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD) != null) { // Success! There's a magnetometer. } else { // Failure! No magnetometer. }
Java
private SensorManager sensorManager; ... sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); if (sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD) != null){ // Success! There's a magnetometer. } else { // Failure! No magnetometer. }
注意:Android 不要求设备制造商构建任何 特定类型的传感器集成到他们的 Android 设备中,因此设备可以具有多种多样的 传感器配置。
除了列出设备上的传感器外,您还可以使用
Sensor
类来确定各个应用的
传感器。如果您希望应用根据哪些传感器或
传感器功能。例如,您可以使用 getResolution()
和 getMaximumRange()
方法获取传感器的分辨率和最大测量范围。您还可以使用
getPower()
方法获取传感器的功率要求。
其中的两种公开方法特别适合您希望针对
不同制造商的传感器或不同版本的传感器。例如,如果您的应用
需要监控用户手势(如倾斜和摇晃),那么您可以创建一组数据过滤
具有特定供应商重力传感器和其他
一组数据过滤规则和优化措施,适用于没有重力传感器且
一个加速度计。以下代码示例展示了如何使用 getVendor()
和 getVersion()
方法来执行
这个。在本示例中,我们要寻找一个将供应商列为 Google LLC 的重力传感器,
版本号为 3如果设备上没有该传感器,我们会尝试使用
加速度计。
Kotlin
private lateinit var sensorManager: SensorManager private var mSensor: Sensor? = null ... sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager if (sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY) != null) { val gravSensors: List<Sensor> = sensorManager.getSensorList(Sensor.TYPE_GRAVITY) // Use the version 3 gravity sensor. mSensor = gravSensors.firstOrNull { it.vendor.contains("Google LLC") && it.version == 3 } } if (mSensor == null) { // Use the accelerometer. mSensor = if (sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null) { sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) } else { // Sorry, there are no accelerometers on your device. // You can't play this game. null } }
Java
private SensorManager sensorManager; private Sensor mSensor; ... sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); mSensor = null; if (sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY) != null){ List<Sensor> gravSensors = sensorManager.getSensorList(Sensor.TYPE_GRAVITY); for(int i=0; i<gravSensors.size(); i++) { if ((gravSensors.get(i).getVendor().contains("Google LLC")) && (gravSensors.get(i).getVersion() == 3)){ // Use the version 3 gravity sensor. mSensor = gravSensors.get(i); } } } if (mSensor == null){ // Use the accelerometer. if (sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null){ mSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); } else{ // Sorry, there are no accelerometers on your device. // You can't play this game. } }
另一个有用的方法是 getMinDelay()
方法。
该函数会返回传感器可用于感应数据的最小时间间隔(以微秒为单位)。任何传感器
会返回 getMinDelay()
的非零值
是流式传输
传感器。流式传感器定期感知数据,在 Android 2.3 (API) 中引入
9 级)。如果传感器在您调用 getMinDelay()
方法时返回零,则表示
传感器不是流式传感器,因为它仅在
参数。
getMinDelay()
方法非常有用,因为它
您可以决定
传感器用来获取数据如果应用中的某些功能需要大量流量
捕获率或流式传感器,则可以使用此方法来确定
满足这些要求,然后启用或停用应用中的相关功能
。
注意:并非传感器的最大数据采集速率 必须是传感器框架向应用传送传感器数据的速率。通过 传感器框架通过传感器事件报告数据,而几个因素会影响 您的应用将收到传感器事件。如需了解详情,请参阅监控传感器事件。
监控传感器事件
要监控原始传感器数据,您需要实现通过
SensorEventListener
接口:onAccuracyChanged()
和 onSensorChanged()
。Android 系统调用
这些方法:
- 传感器的准确度发生变化。
在这种情况下,系统会调用
onAccuracyChanged()
方法,提供 通过对更改的Sensor
对象的引用以及 传感器的新精度。准确性由以下四个状态常量之一来表示:SENSOR_STATUS_ACCURACY_LOW
,SENSOR_STATUS_ACCURACY_MEDIUM
,SENSOR_STATUS_ACCURACY_HIGH
, 或SENSOR_STATUS_UNRELIABLE
。 - 传感器报告新值。
在这种情况下,系统会调用
onSensorChanged()
方法,为您提供 一个SensorEvent
对象。一个SensorEvent
对象 包含有关新传感器数据的信息,包括:数据的准确性、 生成数据的传感器、生成数据的时间戳,以及新的 传感器记录的数据。
以下代码展示了如何使用 onSensorChanged()
方法监控
光传感器此示例在 TextView
中显示原始传感器数据
即
在 main.xml 文件中定义为 sensor_data
。
Kotlin
class SensorActivity : Activity(), SensorEventListener { private lateinit var sensorManager: SensorManager private var mLight: Sensor? = null public override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.main) sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager mLight = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT) } override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) { // Do something here if sensor accuracy changes. } override fun onSensorChanged(event: SensorEvent) { // The light sensor returns a single value. // Many sensors return 3 values, one for each axis. val lux = event.values[0] // Do something with this sensor value. } override fun onResume() { super.onResume() mLight?.also { light -> sensorManager.registerListener(this, light, SensorManager.SENSOR_DELAY_NORMAL) } } override fun onPause() { super.onPause() sensorManager.unregisterListener(this) } }
Java
public class SensorActivity extends Activity implements SensorEventListener { private SensorManager sensorManager; private Sensor mLight; @Override public final void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); mLight = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT); } @Override public final void onAccuracyChanged(Sensor sensor, int accuracy) { // Do something here if sensor accuracy changes. } @Override public final void onSensorChanged(SensorEvent event) { // The light sensor returns a single value. // Many sensors return 3 values, one for each axis. float lux = event.values[0]; // Do something with this sensor value. } @Override protected void onResume() { super.onResume(); sensorManager.registerListener(this, mLight, SensorManager.SENSOR_DELAY_NORMAL); } @Override protected void onPause() { super.onPause(); sensorManager.unregisterListener(this); } }
在本示例中,在调用 registerListener()
方法时指定了默认数据延迟 (SENSOR_DELAY_NORMAL
)。数据
延迟(也称作采样率)控制传感器事件发送到应用的时间间隔
onSensorChanged()
回调方法,默认
数据延迟适用于
典型的屏幕方向变化,并使用 200,000 微秒的延迟。您可以指定其他
数据延迟,例如 SENSOR_DELAY_GAME
(20,000 微秒)
延迟)、SENSOR_DELAY_UI
(延迟 60,000 微秒)或 SENSOR_DELAY_FASTEST
(延迟 0 微秒)。从 Android 3.0 (API
级别 11),您还可以将延迟时间指定为绝对值(以微秒为单位)。
您指定的延迟只是建议的延迟。Android 系统和其他应用 改变这种延迟最佳做法是指定尽可能长的延迟时间,因为 通常,系统使用的延迟时间会比您指定的延迟时间短(也就是说,您应该选择 但仍能满足应用需求的最低采样率)。使用较长的延迟时间会导致 可以降低处理器上的负载,从而降低功耗。
没有公共方法可以确定传感器框架的发送速率 将传感器事件发送到您的应用不过,您可以使用与每个 传感器事件计算多个事件的采样率。您不必更改 采样率(延迟)的值。如果出于某种原因,您确实需要更改延迟时间, 必须取消注册,然后重新注册传感器监听器。
另外还需要注意的是,此示例使用 onResume()
,
用于注册和取消注册传感器事件的 onPause()
回调方法
监听器。最佳做法是始终停用不需要的传感器,尤其是在
活动已暂停。否则,可能几个小时后就会耗尽电池电量,因为某些传感器
具有很高的功耗要求,并且可能会很快耗尽电池电量。系统
在屏幕关闭时不会自动停用传感器。
处理不同的传感器配置
Android 没有为设备指定标准的传感器配置 这意味着设备制造商可以将他们需要的任何传感器配置纳入其 采用 Android 的手机。因此,设备可能会包含多种 各种传感器。 如果您的应用依赖于特定类型的传感器,则必须确保 传感器,以便您的应用可以成功运行。
有两种方法可以确保设备上存在特定的传感器:
- 在运行时检测传感器,并根据需要启用或停用应用功能。
- 使用 Google Play 过滤器定位具有特定传感器配置的设备。
下面将分别讨论这两种方法。
在运行时检测传感器
如果您的应用使用特定类型的传感器,但不依赖于它,您可以使用 传感器框架在运行时检测传感器,然后停用或启用应用功能 视情况而定。例如,导航应用可以使用温度传感器, 压力传感器、GPS 传感器和地磁场传感器,用于显示温度、气压 压力、位置和罗盘方位。如果设备没有压力传感器,您可以使用 传感器框架在运行时检测压力传感器的缺失,然后停用 显示压力的部分。例如,以下代码会检查 设备上是否有压力传感器:
Kotlin
private lateinit var sensorManager: SensorManager ... sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager if (sensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE) != null) { // Success! There's a pressure sensor. } else { // Failure! No pressure sensor. }
Java
private SensorManager sensorManager; ... sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); if (sensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE) != null){ // Success! There's a pressure sensor. } else { // Failure! No pressure sensor. }
使用 Google Play 过滤器定位特定的传感器配置
如果您要在 Google Play 上发布应用,可以使用
<uses-feature>
元素,用于从符合以下条件的设备中滤除您的应用:
具有适合您应用的传感器配置。通过
<uses-feature>
元素具有多个硬件描述符,可用于过滤
根据是否存在特定传感器来调整应用。您可以列出的传感器包括:
加速度计、气压计、罗盘(地磁场)、陀螺仪、光和近程。通过
以下是一个清单条目示例,它过滤没有加速度计的应用:
<uses-feature android:name="android.hardware.sensor.accelerometer" android:required="true" />
如果您将此元素和描述符添加到应用的清单中,用户将看到 应用在 Google Play 上架。
只有在您的应用需要的情况下,您才能将描述符设置为 android:required="true"
。
完全依靠特定的传感器。如果您的应用使用传感器来实现某些功能,但
仍然在没有传感器的情况下运行,则应在 <uses-feature>
中列出该传感器
但要将描述符设置为 android:required="false"
。这有助于确保
即使设备没有该传感器,也可以安装您的应用。这也是一个
可帮助您跟踪应用所使用功能的项目管理最佳实践。
请注意,如果您的应用使用特定的传感器,但在没有传感器的情况下仍会运行,
则您应在运行时检测传感器,并像之前一样停用或启用应用功能
适当的选择。
传感器坐标系
通常,传感器框架使用标准的 3 轴坐标系来表示数据值。 对于大多数传感器,在设备运行时,以设备屏幕为参照物定义坐标系 保持其默认方向(参见图 1)。当设备处于默认屏幕方向时, X 轴水平指向右侧,Y 轴垂直指向上方,Z 轴为垂直方向 轴指向屏幕外侧。在此系统中,屏幕背后的坐标 Z 值为负。以下传感器使用此坐标系:
关于这个坐标系,最重要的是需要了解:轴并不是 在设备的屏幕方向(即传感器的坐标系)发生变化时交换 绝不会随着设备的移动而变化。此行为与 OpenGL 坐标系
还需要注意一点是,您的应用不能假定设备的自然 (默认)屏幕方向为纵向。许多平板设备的自然屏幕方向为横屏。且 传感器坐标系始终以设备的自然屏幕方向为基础。
最后,如果您的应用将传感器数据与屏幕显示相匹配,您需要使用
getRotation()
方法确定屏幕旋转角度,然后使用
要映射的 remapCoordinateSystem()
方法
将传感器坐标映射到屏幕坐标。即使您的清单指定了
仅限纵向显示
注意:某些传感器和方法使用的坐标系
相对于世界参照系(而不是设备的参照系)。这些
传感器和方法返回的数据表示设备相对于
地球。如需了解详情,请参阅 getOrientation()
方法、getRotationMatrix()
方法、屏幕方向
传感器和旋转矢量
传感器。
传感器速率限制
为了保护有关用户的潜在敏感信息(如果您的应用以 Android 12(API 级别 31)或更高版本,则系统会对刷新施加限制 特定移动传感器和位置传感器的数据速率。这些数据 包含由设备的 加速度计, 陀螺仪和 地磁场 传感器。
刷新率限制取决于您访问传感器数据的方式:
- 如果您调用
registerListener()
监控传感器事件的方法,则传感器采样率为 限制为 200Hz。这适用于registerListener()
方法。 - 如果您使用
SensorDirectChannel
类,则传感器采样率限制为RATE_NORMAL
,通常约为 50 Hz。
如果您的应用需要以更高的速率收集移动传感器数据,则必须
声明
HIGH_SAMPLING_RATE_SENSORS
权限,如以下代码段所示。否则,如果您的应用尝试
在不声明此权限的情况下以更高的速率收集移动传感器数据,
会发生 SecurityException
。
<manifest ...> <uses-permission android:name="android.permission.HIGH_SAMPLING_RATE_SENSORS"/> <application ...> ... </application> </manifest>
访问和使用传感器的最佳做法
在设计传感器实现时,请务必遵循 部分。这些准则是推荐采用的最佳实践,适用于所有传感器使用者 框架来访问传感器并获取传感器数据。
仅在前台采集传感器数据
在搭载 Android 9(API 级别 28)或更高版本的设备上,在 具有下列限制:
鉴于这些限制,最好在 应用在前台运行或作为应用的一部分运行 前台服务。
取消注册传感器监听器
使用完传感器或在传感器使用完毕后,请务必取消注册传感器的监听器
活动暂停。如果注册了传感器监听器且其 activity 已暂停,则传感器将
继续获取数据并使用电池资源,除非您取消注册传感器。以下
代码展示了如何使用 onPause()
方法取消注册监听器:
Kotlin
private lateinit var sensorManager: SensorManager ... override fun onPause() { super.onPause() sensorManager.unregisterListener(this) }
Java
private SensorManager sensorManager; ... @Override protected void onPause() { super.onPause(); sensorManager.unregisterListener(this); }
如需了解详情,请参阅 unregisterListener(SensorEventListener)
。
使用 Android 模拟器进行测试
Android Emulator 包含一组虚拟传感器控件, 您可以测试加速度计、环境温度计、磁力计等传感器, 例如近距离、光照等
模拟器与运行 SdkController 传感器 应用。请注意,此应用仅适用于运行 Android 4.0 (API 级别 14)或更高版本。(如果设备运行的是 Android 4.0,它必须 已安装修订版 2。)SdkControllerSensor 应用会监控 设备上的传感器并将其传输到模拟器。模拟器是 然后根据从 。
您可以在 以下位置:
$ your-android-sdk-directory/tools/apps/SdkController
如需在设备和模拟器之间传输数据,请按照以下说明操作 步骤:
- 检查 USB 调试。
- 使用 USB 数据线将设备连接到开发计算机。
- 在设备上启动 SdkControllerSensor 应用。
- 在应用中,选择您要模拟的传感器。
运行以下
adb
命令:- 启动模拟器。现在,您应该能够将转换应用于 来移动模拟器。
$ adb forward tcp:1968 tcp:1968
注意 :如果您对画面的移动
实体设备未对模拟器进行转换,请尝试运行
adb
命令。
有关详情,请参阅 Android 模拟器指南。
请勿阻塞 onSensorChanged() 方法
传感器数据可以以很高的频率变化,这意味着系统可能会频繁调用 onSensorChanged(SensorEvent)
方法。最佳做法是
应在 onSensorChanged(SensorEvent)
方法中执行尽可能少的操作,以免阻塞它。如果您的
应用要求您对传感器数据进行任何数据过滤或减少操作,则应执行
在 onSensorChanged(SensorEvent)
方法之外运行的应用。
避免使用已弃用的方法或传感器类型
一些方法和常量已弃用。
具体而言,TYPE_ORIENTATION
传感器类型已弃用。应改用 getOrientation()
方法来获取屏幕方向数据。同样,
已废弃 TYPE_TEMPERATURE
传感器类型。您应该使用
改为在设备上使用 TYPE_AMBIENT_TEMPERATURE
传感器类型
运行 Android 4.0 的设备
使用传感器之前应先进行验证
在尝试从传感器采集数据之前,应始终先验证设备上是否存在该传感器。错误做法 我们假设某个传感器的存在只是因为它是一个经常使用的传感器。设备制造商 不需要在其设备中提供任何特定的传感器。
谨慎选择传感器延迟
使用 registerListener()
方法注册传感器时,请务必选择适合您
应用或用例。传感器能以非常高的频率提供数据。允许系统发送
您不需要的额外数据会浪费系统资源和消耗电池电量。