4. 健康数据采集基础

Wear OS 上的健康数据采集,本质上是一条从“物理传感器”到“应用可读数据”的链路。手表里的心率传感器、加速度计、计步器等硬件,先把人体的生理与运动状态转换为电信号,再由系统底层驱动和传感器框架加工成标准化的数据流,最终通过 SensorManager 暴露给应用。理解这条链路,才能写出稳定、省电、合规的健康应用。

一、Wear OS 常见健康相关传感器类型

Wear OS 通过 Android Sensor API 暴露的传感器,按数据特性大致可分为三类。第一类是连续型传感器,如心率传感器(TYPE_HEART_RATE),它以固定采样率持续输出每分钟心跳次数(bpm),适合运动中心率曲线、静息心率监测等场景。第二类是事件型/变化型传感器,如计步器(TYPE_STEP_COUNTER)和步数检测器(TYPE_STEP_DETECTOR):前者返回自设备重启以来的累计步数,后者在每次检测到一步时触发一次事件。第三类是运动与环境传感器,如加速度计、陀螺仪,用于识别走路、跑步、睡眠姿态等。

需要特别区分的是,TYPE_STEP_COUNTER 返回的是“累计值”,应用必须自己保存基线并做差值计算,才能得到某段时间内的步数;而 TYPE_STEP_DETECTOR 只告诉你“发生了一步”,不提供总数。心率传感器则受佩戴状态影响很大,未佩戴或佩戴过松时可能返回 0 或不可用状态,代码中必须处理这种异常。

二、SensorManager 的获取与传感器能力查询

SensorManager 是访问传感器的入口,通过 getSystemService(SENSOR_SERVICE) 获取。拿到它之后,不要假设设备一定具备某个传感器,而应先查询:

val sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
val heartRateSensor = sensorManager.getDefaultSensor(Sensor.TYPE_HEART_RATE)
val stepCounterSensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER)

if (heartRateSensor == null) {
    // 该设备不支持心率传感器,降级处理
}

如果 getDefaultSensor() 返回 null,说明硬件不支持,应用应给出明确提示而不是静默失败。此外,还可以通过 sensor.maximumRange、sensor.resolution、sensor.power 了解量程、精度和功耗,为采样策略提供依据。

三、心率与步数数据的获取方式

获取数据有两种典型方式:监听器回调和主动读取。对于心率,通常注册 SensorEventListener,在 onSensorChanged 中拿到 SensorEvent.values[0],即当前 bpm。采样率建议用 SENSOR_DELAY_NORMAL 或 SENSOR_DELAY_UI,运动场景可用 SENSOR_DELAY_GAME,但更高频率意味着更高功耗。

val listener = object : SensorEventListener {
    override fun onSensorChanged(event: SensorEvent) {
        if (event.sensor.type == Sensor.TYPE_HEART_RATE) {
            val bpm = event.values[0]
            if (bpm > 0) updateHeartRate(bpm)
        }
    }
    override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {}
}
sensorManager.registerListener(listener, heartRateSensor, SensorManager.SENSOR_DELAY_NORMAL)

步数采集则更适合用累计值做差值。首次收到 TYPE_STEP_COUNTER 事件时记录基线 baseSteps,之后每次用 event.values[0] - baseSteps 得到本次会话步数。注意该累计值在设备重启后会清零,因此基线要随重启重新建立。若只需判断“是否在走路”,可用 TYPE_STEP_DETECTOR 做轻量触发。

四、权限申请与用户授权

从 Android 10(API 29)起,心率等健康数据需要 BODY_SENSORS 权限;步数在部分版本中通过 ACTIVITY_RECOGNITION 权限管理。Wear OS 上还需注意:若应用在后台持续采集,可能需要 FOREGROUND_SERVICE 及对应的前台服务类型声明。权限必须在 AndroidManifest.xml 中声明,并在运行时动态申请:

<uses-permission android:name="android.permission.BODY_SENSORS" />
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />

运行时申请使用 ActivityResultLauncher,根据用户是否授权决定后续行为。若用户拒绝,应解释用途并引导到设置页,而不是反复弹窗骚扰。健康数据属于敏感信息,采集前应明确告知用途、采集频率和存储方式,遵循最小必要原则。

在真机或模拟器上验证时,可先检查 getDefaultSensor() 是否为 null,再观察 onSensorChanged 是否按预期触发;心率数据在未佩戴时可能长时间不更新,这属于正常现象。
Wear OS 健康数据采集链路 硬件传感器 心率光电传感器 加速度计 / 计步器 HAL / 驱动层 信号采样与滤波 原始数据标准化 Sensor Framework SensorManager SensorEventListener 健康应用 数据展示 / 存储 业务逻辑 权限与授权关卡 BODY_SENSORS · ACTIVITY_RECOGNITION · 前台服务声明 心率数据流 TYPE_HEART_RATE → values[0] (bpm) 采样率:SENSOR_DELAY_NORMAL 异常:未佩戴时 bpm = 0 处理:过滤 0 值,更新 UI 步数数据流 TYPE_STEP_COUNTER → 累计值 首次记录 baseSteps 基线 本次步数 = 当前值 − baseSteps 重启后累计值清零,需重建基线 数据采集需遵循最小必要原则,采集前明确告知用户用途与频率

五、采集策略与工程注意事项

在真实工程中,采集策略直接决定续航与用户体验。心率不需要每秒多次采样,静息监测用 SENSOR_DELAY_NORMAL 即可;运动场景可临时提高频率,结束后及时 unregisterListener。步数累计值读取频率低,可在页面可见时注册,不可见时注销。所有监听器都应在 onPause 或 onStop 中释放,避免后台耗电。

另一个关键点是数据可信度。心率传感器在剧烈运动、手腕晃动、佩戴过松时可能输出跳变值,工程上常用滑动窗口均值或中值滤波做平滑;步数累计值在设备重启、系统更新后可能重置,应用应把“会话步数”和“历史累计”分开存储,避免把系统累计值直接当作业务总步数。

不要假设所有 Wear OS 设备都具备心率传感器。部分入门款或特定区域版本可能缺失该硬件,代码必须做能力检测与降级,否则会在 registerListener 时传入 null 导致崩溃。

把以上环节串起来:先查询传感器能力,再申请并确认权限,然后按场景选择采样率注册监听器,在回调中解析心率 bpm 或步数累计值,最后做异常过滤、平滑与生命周期管理。这条链路清晰之后,后续的传感器融合、后台采集与数据同步才有可靠的基础。