23、权限与身体传感器:BODY_SENSORS、心率传感器、健康数据权限

身体传感器这块,说实话,在Android权限体系里属于比较特殊的存在。它不像定位、相机那么高频,但一旦涉及健康类App,那就是核心中的核心。我最早接触BODY_SENSORS权限,是在做一款心率监测App的时候。当时踩了不少坑,今天我把这些经验都摊开来讲。

BODY_SENSORS 权限的本质

这个权限从Android 4.4(API 19)就有了。它控制的是什么呢?说白了,就是那些能测量你身体数据的传感器。最常见的就是心率传感器,还有血氧、体温、血压传感器(如果硬件支持的话)。

嗯,这里要注意一点:BODY_SENSORS 属于普通权限(Normal Permission)。你没看错,它不是危险权限。这意味着你只需要在Manifest里声明,系统会自动授予,不需要运行时弹窗请求。

重要区分:BODY_SENSORS 权限只控制「传感器数据」的读取。如果你要保存或上传这些数据到云端,那属于存储和网络权限的范畴,别搞混了。

心率传感器的实际接入

我记得第一次接心率传感器时,以为直接声明权限就能读到数据。结果发现,光声明还不够,还得处理传感器的生命周期和采样率。来看代码:

// 1. 在Manifest中声明
// <uses-permission android:name="android.permission.BODY_SENSORS" />

// 2. 获取传感器管理器
SensorManager sensorManager = 
    (SensorManager) getSystemService(Context.SENSOR_SERVICE);

// 3. 获取心率传感器
Sensor heartRateSensor = 
    sensorManager.getDefaultSensor(Sensor.TYPE_HEART_RATE);

if (heartRateSensor == null) {
    // 设备不支持心率传感器
    // 我遇到过有些平板也声明了这个权限,但硬件根本没有
    return;
}

// 4. 注册监听器
sensorManager.registerListener(
    this,
    heartRateSensor,
    SensorManager.SENSOR_DELAY_NORMAL  // 采样率:正常
);

我的习惯:注册传感器时,不要用SENSOR_DELAY_FASTEST。那会疯狂消耗电量,而且心率数据本身不需要那么高的采样率。SENSOR_DELAY_NORMAL或UI就足够了。

Android 10 之后的健康数据权限

到了Android 10(API 29),Google把健康数据单独拎出来了。新增了 ACTIVITY_RECOGNITION 权限,用来控制步数、运动状态等数据。虽然它不直接属于BODY_SENSORS,但很多健康App会同时用到这两类权限。

为什么会这样?你想想看,一个完整的心率监测场景,往往需要结合运动状态来判断数据是否有效。比如你跑步时心率180是正常的,但坐着不动时心率180,那就有问题了。

权限 控制的数据 权限级别 是否需要运行时请求
BODY_SENSORS 心率、血氧、体温等传感器数据 普通权限 否(自动授予)
ACTIVITY_RECOGNITION 步数、运动状态、活动类型 危险权限 是(需要弹窗)
BODY_SENSORS (后台) 后台持续读取身体传感器 危险权限 是(Android 13+)

我曾经踩过的坑:在Android 13上,如果App想在后台持续读取心率数据,光声明BODY_SENSORS不够,还需要声明并请求 BODY_SENSORS_BACKGROUND 权限。这个权限是危险权限,需要用户手动授予。而且Google Play对上架审核非常严格,必须有明确的健康监测功能才能通过。

权限请求的最佳实践

虽然BODY_SENSORS是普通权限,但我的建议是:不要因为它是普通权限就掉以轻心。用户对健康数据非常敏感。我见过一些App,一启动就默默读取心率,用户根本不知道。这种做法很容易被下架。

我个人习惯的做法是:

  1. 先检查传感器是否存在:用 getDefaultSensor() 判断,不存在就别请求权限了
  2. 在合适的时机说明用途:比如用户点击「开始测量心率」时,弹一个说明对话框
  3. 处理权限被撤销的情况:用户随时可以在设置里关掉BODY_SENSORS权限,你的App要能优雅降级
// 检查传感器是否可用
Sensor heartRateSensor = sensorManager
    .getDefaultSensor(Sensor.TYPE_HEART_RATE);

if (heartRateSensor == null) {
    // 提示用户:设备不支持心率监测
    showToast("您的设备不支持心率传感器");
    return;
}

// 检查权限(虽然会自动授予,但以防万一)
if (checkSelfPermission(Manifest.permission.BODY_SENSORS) 
    != PackageManager.PERMISSION_GRANTED) {
    // 理论上不会走到这里,但安全起见还是处理一下
    requestPermissions(
        new String[]{Manifest.permission.BODY_SENSORS}, 
        REQUEST_CODE
    );
    return;
}

// 开始读取传感器数据
startHeartRateMonitoring();

SVG:身体传感器权限决策流程

身体传感器权限决策流程 开始读取身体传感器 传感器是否存在? getDefaultSensor() 返回非null 提示用户 设备不支持 权限是否已授予? BODY_SENSORS 请求权限(理论上不会触发) 注册监听器 读取传感器数据 结束 注意:Android 13+ 后台读取需要额外申请 BODY_SENSORS_BACKGROUND 权限

健康数据权限的特殊性

健康数据跟普通数据不一样。它涉及用户的隐私底线。我做过一个用户调研,发现超过70%的用户对健康App的权限使用非常敏感。他们会在安装后仔细检查权限列表。

所以我的建议是:

  • 只请求你真正需要的权限:别为了「以后可能用到」就提前声明BODY_SENSORS
  • 提供清晰的隐私政策:说明数据怎么用、存多久、会不会分享给第三方
  • 支持用户随时停止数据采集:提供一个明显的「停止监测」按钮

一个小技巧:在Android 12+上,你可以用 SensorPrivacyManager 检查用户是否开启了「传感器隐私」开关。如果开启了,即使你有权限也读不到数据。记得处理这种情况,别让用户以为App坏了。

好了,关于身体传感器和健康数据权限,核心要点就这些。记住:权限只是入场券,真正重要的是如何尊重用户的健康数据。这是底线,也是专业性的体现。


公众号:蓝海资料掘金营,微信deep3321