Sensors API:是什么、传感器类型及传感器使用

作者: IT Sectr 发布日期: 2026-03-26 阅读时间: 10 分钟

Sensors API — 是Android平台用于访问设备硬件传感器的接口。API提供了从加速度计、陀螺仪、磁力计、光传感器和其他传感器获取数据的统一方式。根据Google,2026的数据,超过95%的现代Android设备至少配备三种类型的传感器,这为开发上下文感知应用程序开辟了广阔的可能性。

要点

  • Sensors API — 用于处理设备硬件传感器的统一Android接口。
  • 三个类别 — Motion、Position和Environment传感器,具有不同的测量原理。
  • SensorManager — 用于获取传感器列表和注册监听器的系统服务。
  • 更新频率通过SENSOR_DELAY常量从NORMAL到FASTEST进行设置。
  • 虚拟传感器 — Gravity、Rotation Vector和Linear Acceleration基于物理传感器的组合。

Android中的Sensors API是什么?

Sensors API — 是Android Framework的编程接口,为开发者提供对移动设备硬件传感器的访问。API自1.0版本起就是Android SDK的一部分,可通过android.hardware包访问。该接口抽象了不同制造商(Qualcomm、MediaTek、Samsung Exynos)传感器实现之间的差异,并提供统一的传感器工作模型。

Sensors API的主要功能

API允许执行三个关键操作:获取可用传感器列表、注册监听器以接收数据以及管理读取更新频率。SensorManager是所有操作的中心访问点。系统通过onSensorChanged回调通知应用程序,传递包含float值数组的SensorEvent对象。

Sensors API的演进

在Android存在期间,API经历了几个发展阶段。2.3(Gingerbread)版本中引入了Batch Processing支持——将传感器事件分组以降低能耗。Android 4.0(Ice Cream Sandwich)添加了Gravity和Linear Acceleration虚拟传感器。从Android 8.0开始,系统限制了对传感器的后台访问以提高隐私性。

kotlin
val sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
val sensorList: List<Sensor> = sensorManager.getSensorList(Sensor.TYPE_ALL)
sensorList.forEach { sensor ->
    Log.d("传感器", "${sensor.name} — ${sensor.type}")
}

限制和要求

并非所有设备都有相同的传感器集。应用程序在注册监听器之前必须检查特定传感器的可用性。Android模拟器仅支持有限的传感器集——加速度计和磁力计。测试其他传感器需要物理设备。从Android 12开始,应用程序必须在清单中声明传感器使用。

Android传感器类型:Motion、Position、Environment

Android将所有传感器分为三类:Motion(运动)、Position(位置)和Environment(环境)。Motion传感器包括加速度计、陀螺仪和计步器。Position传感器包括磁力计和Orientation。Environment——光传感器、压力、温度和湿度传感器。

类别传感器类型(常量)物理/虚拟
Motion加速度计TYPE_ACCELEROMETER物理
Motion陀螺仪TYPE_GYROSCOPE物理
Motion计步器TYPE_STEP_COUNTER物理
MotionGravityTYPE_GRAVITY虚拟
Position磁力计TYPE_MAGNETIC_FIELD物理
PositionRotation VectorTYPE_ROTATION_VECTOR虚拟
EnvironmentTYPE_LIGHT物理
Environment压力TYPE_PRESSURE物理

Motion传感器:加速度计和陀螺仪

加速度计沿三个轴(X、Y和Z)测量以m/s²为单位的加速度。数值包括重力(静止状态下Z轴为9.8 m/s²)。陀螺仪测量以rad/s为单位的角速度——设备绕每个轴的旋转速度。这两种传感器的组合用于导航、游戏和AR应用。

kotlin
class SensorActivity : Activity(), SensorEventListener {
    override fun onSensorChanged(event: SensorEvent) {
        if (event.sensor.type == Sensor.TYPE_ACCELEROMETER) {
            val x = event.values[0]
            val y = event.values[1]
            val z = event.values[2]
            textView.text = "X: $x, Y: $y, Z: $z"
        }
    }
    override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {}
}

Position传感器:磁力计和方向

磁力计(TYPE_MAGNETIC_FIELD)沿三个轴测量以微特斯拉(µT)为单位的磁场。用作数字指南针——与加速度计结合使用可以确定设备的方位角。Rotation Vector——一种虚拟传感器,结合陀螺仪、加速度计和磁力计的数据以精确确定方向。

Environment传感器:光、压力、温度

光传感器(TYPE_LIGHT)测量以勒克斯(lx)为单位的外部光照水平。用于自动调节屏幕亮度。压力传感器(TYPE_PRESSURE)测量以百帕(hPa)为单位的大气压力——在导航应用中用于确定海拔高度。

Sensors API架构如何工作

Sensors API构建在客户端-服务器架构上。应用程序充当客户端,SensorManager充当Android系统服务。当应用程序通过registerListener注册监听器时,SensorManager连接到HAL(硬件抽象层)——在Linux内核级别运行的低级传感器驱动程序。

传感器事件的生命周期

HAL驱动程序从硬件芯片接收原始数据,过滤噪声,并通过SensorService(系统进程)将数据向上传递到应用程序。数据作为SensorEvent对象传输,包含float值数组values和以纳秒为单位的时间戳。事件频率取决于所选的传递模式。

事件传递模式

注册监听器时,开发者通过SENSOR_DELAY_NORMAL(200 ms)、SENSOR_DELAY_UI(60 ms)、SENSOR_DELAY_GAME(20 ms)和SENSOR_DELAY_FASTEST(0 ms——最大频率)常量指定事件之间所需的延迟。实际频率可能有所不同——系统优化能耗。

kotlin
val sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
sensorManager.registerListener(
    this,
    sensor,
    SensorManager.SENSOR_DELAY_GAME
)

批处理(Batch Processing)

Android 2.3开始,传感器支持批处理模式——事件在FIFO缓冲区中累积并一次性传递。这允许处理器更长时间保持在睡眠模式,将能耗降低高达60%。缓冲区大小取决于传感器芯片,在Sensor.fifoMaxEventCount字段中指定。

使用SensorManager访问传感器

SensorManager — 可通过getSystemService(Context.SENSOR_SERVICE)访问的系统服务。提供获取传感器列表、获取特定默认传感器以及注册/取消监听器的方法。SensorManager——单例,整个应用程序只有一个实例。

检查传感器可用性

在使用传感器之前,必须检查其是否存在。getDefaultSensor(type)方法在设备上不存在传感器时返回null获取null而不进行检查将在注册监听器时导致NullPointerException。所有传感器的列表由getSensorList(type)方法返回。

kotlin
fun checkSensorAvailability(type: Int): Boolean {
    val sensorManager =
        getSystemService(Context.SENSOR_SERVICE) as SensorManager
    return sensorManager.getDefaultSensor(type) != null
}

// 使用:
if (checkSensorAvailability(Sensor.TYPE_GYROSCOPE)) {
    Log.d("Sensor", "陀螺仪可用")
}

注册和取消监听器

监听器通过registerListener(listener, sensor, delay)注册。重要:必须在onPause()方法中通过unregisterListener(listener)取消监听器。如果不这样做,应用程序将继续接收传感器事件,即使在后台也会消耗电池。Android 8+在logcat中显示关于未注册监听器的警告。

处理精度变化

onAccuracyChanged(sensor, accuracy)方法在传感器精度变化时被调用。值:SENSOR_STATUS_ACCURACY_HIGH、MEDIUM、LOW和UNRELIABLE。接收到UNRELIABLE时,应忽略传感器数据直到精度恢复。例如,磁力计需要校准——以8字形摇晃设备。

Kotlin中传感器使用的代码示例

让我们看看Kotlin Android应用中使用Sensors API的实际示例。第一个示例——使用加速度计确定屏幕方向。第二个——带有校准的磁力计读数。第三个——使用计步器的步数检测器。

确定设备方向

使用加速度计和磁力计的组合来确定方向。SensorManager.getRotationMatrix()方法计算旋转矩阵,getOrientation()提取pitch、roll和azimuth角度。Azimuth(方位角)——相对于磁北的角度,以弧度为单位。

kotlin
val gravity = FloatArray(3)
val geomagnetic = FloatArray(3)
val rotationMatrix = FloatArray(9)
val orientation = FloatArray(3)

SensorManager.getRotationMatrix(
    rotationMatrix, null, gravity, geomagnetic
)
SensorManager.getOrientation(rotationMatrix, orientation)
// orientation[0] — azimuth, [1] — pitch, [2] — roll
val azimuthDeg = Math.toDegrees(orientation[0].toDouble())

使用计步器的步数检测器

计步器(TYPE_STEP_COUNTER)返回自设备上次重启以来用户走过的总步数。传感器在硬件级别工作——即使应用程序未运行也处于活动状态。要获取会话期间的步数,需要保存初始值并计算差值。

kotlin
var initialSteps = 0
var isInitialized = false

override fun onSensorChanged(event: SensorEvent) {
    if (event.sensor.type == Sensor.TYPE_STEP_COUNTER) {
        if (!isInitialized) {
            initialSteps = event.values[0].toInt()
            isInitialized = true
        }
        val currentSteps = event.values[0].toInt()
        val sessionSteps = currentSteps - initialSteps
        Log.d("步数", "会话步数:$sessionSteps")
    }
}

基于光传感器的自适应亮度

光传感器允许根据环境条件调整界面。在低光照(低于10 lx)下可以切换到深色主题。在强阳光下(超过10000 lx)——可以增加对比度。去噪使用最后5个值的移动平均值。

虚拟传感器和融合算法

Android提供了几个没有直接硬件对应物的虚拟传感器。虚拟传感器基于物理传感器的组合计算其读数。这减轻了开发者的负担——系统自行实现数据融合算法。

Gravity和Linear Acceleration

Gravity(TYPE_GRAVITY)传感器使用低通滤波器从加速度计读数中提取重力分量。Linear Acceleration(TYPE_LINEAR_ACCELERATION)——反过来,去除重力并仅保留设备的线性加速度。Gravity和Linear Acceleration之和给出加速度计的原始读数。

Rotation Vector

Rotation Vector——最复杂的虚拟传感器。它结合了陀螺仪(高频变化)、加速度计(重力向量)和磁力计(相对于北方的方向)的数据。结果——描述设备在空间中绝对方向的四元数。用于AR应用和VR头显。

Game Rotation Vector

Game Rotation Vector——不使用磁力计的Rotation Vector简化版本。这提供了较低的方位角精度,但更高的更新频率和稳定性。推荐用于低延迟重要的游戏,而非相对于北方的绝对方向。

传感器使用中的能耗优化

传感器——设备中最耗能的组件之一。加速度计和陀螺仪在最大轮询频率下可以在3-4小时连续使用中耗尽电池。优化传感器工作是使用Sensors API的任何应用的关键任务。

选择最佳延迟

不要在没有必要的情况下使用SENSOR_DELAY_FASTEST。对于UI动画,SENSOR_DELAY_UI(60 ms)就足够了。对于屏幕方向确定——SENSOR_DELAY_NORMAL(200 ms)。频率越高,处理器在活动状态下的时间就越多。NORMAL和FASTEST之间的能耗差异高达10倍。

在后台取消监听器

Android 8.0(API 26)开始,后台应用程序接收传感器事件的频率降低。在Android 12+中,后台访问Motion和Position传感器需要BODY_SENSORS_BACKGROUND权限。在应用程序进入后台模式时取消监听器注册——这可以延长设备的电池寿命。

批处理和FIFO缓冲区

通过registerListener(listener, sensor, delay, maxReportLatencyUs)方法使用批处理。maxReportLatencyUs参数指定事件传递的最大延迟(以微秒为单位)。当值为1000000(1秒)时,事件在传感器的FIFO缓冲区中累积并每秒传递一次——处理器更少地从睡眠中唤醒。

常见问题

所有Android设备上都有哪些传感器?

最小集——加速度计和磁力计。这两个传感器存在于超过95%的设备上。陀螺仪、光传感器和接近传感器——在现代型号的70-80%上。其他传感器(压力、温度、湿度、计步器)较不常见,取决于设备的价位。

TYPE_ACCELEROMETER和TYPE_LINEAR_ACCELERATION有什么区别?

TYPE_ACCELEROMETER返回包括重力在内的完整加速度(9.8 m/s²)。TYPE_LINEAR_ACCELERATION返回不含重力的加速度——仅来自设备运动的加速度。如果设备静止不动,加速度计将在Z轴上显示9.8 m/s²,而Linear Acceleration在所有轴上显示0。

如何检查设备是否有需要的传感器?

使用getPackageManager().hasSystemFeature()配合相应的常量:FEATURE_SENSOR_ACCELEROMETER、FEATURE_SENSOR_GYROSCOPE、FEATURE_SENSOR_PROXIMITY等。替代方法——调用getDefaultSensor(type)并检查结果是否为null。第一种方法更适合在初始化阶段进行检查。

为什么传感器数值会跳动以及如何平滑它们?

来自传感器的原始数据包含噪声。要平滑数据,使用低通滤波器:newValue = alpha * rawValue + (1 — alpha) * previousValue。系数alpha = 0.1-0.3在响应性和平滑度之间提供良好的平衡。对于陀螺仪,还使用高通滤波器来消除零漂移。

可以在后台使用传感器吗?

可以,但有局限性。从Android 8.0开始,后台应用的传感器事件频率会降低。从Android 12开始,后台访问传感器需要BODY_SENSORS_BACKGROUND权限。对于后台工作,建议使用带有通知的Foreground Service。

总结

  • Sensors API — 通过SensorManager从设备硬件传感器获取数据的统一Android接口。
  • 三个类别 — Motion(加速度计、陀螺仪)、Position(磁力计)和Environment(光、压力),具有不同的工作原理和应用。
  • 虚拟传感器 — Gravity、Linear Acceleration和Rotation Vector基于物理传感器数据的融合,没有硬件对应物。
  • 优化 — 选择正确的延迟(SENSOR_DELAY_NORMAL、UI、GAME、FASTEST)和使用批处理可将能耗降低高达60%。
  • 限制 — Android 8+降低后台传感器频率,Android 12+后台访问需要BODY_SENSORS_BACKGROUND。
  • 基本检查 — 在注册监听器之前,通过getDefaultSensor或hasSystemFeature检查传感器的可用性。
  • 使用低通滤波器平滑噪声,并在进入后台时取消监听器注册以节省电池。

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读