如何用react-native-ble-manager获取智能手环心率并完成采集
React Native 基于react-native-ble-manager读取智能手环心率的落地实现
前置准备
- 完成react-native-ble-manager的初始化,按平台要求申请对应蓝牙权限:安卓12及以上需申请
BLUETOOTH_SCAN、BLUETOOTH_CONNECT权限,安卓11及以下需额外申请定位权限;iOS需在Info.plist中添加NSBluetoothAlwaysUsageDescription字段 - 提前确认目标手环的心率服务UUID、心率特征值UUID:通用BLE标准心率服务UUID为
0000180D-0000-1000-8000-00805F9B34FB,标准心率测量特征值UUID为00002A37-0000-1000-8000-00805F9B34FB,若为定制化手环需通过抓包工具确认实际UUID
核心实现流程
1. 基础实例初始化与设备连接
import BleManager from 'react-native-ble-manager'; import { NativeModules, NativeEventEmitter } from 'react-native'; // 初始化BLE事件监听发射器 const BleManagerEmitter = new NativeEventEmitter(NativeModules.BleManager); // 绑定目标手环并完成连接 const connectDevice = async (targetDeviceId) => { try { // 建立蓝牙连接,超时时间设为10秒 await BleManager.connect(targetDeviceId); // 等待设备握手完成后再发现服务,避免部分手环识别异常 await new Promise(resolve => setTimeout(resolve, 500)); // 扫描该设备下所有服务与特征值 await BleManager.discoverAllServicesAndCharacteristicsForDevice(targetDeviceId); } catch (error) { console.log('设备连接异常', error); } }
2. 开启心率数据通知
心率数据属于设备主动推送类型,需开启特征值通知后才能接收上报数据:
// 定义常量,替换为实际设备的UUID const HEART_RATE_SERVICE_UUID = '0000180D-0000-1000-8000-00805F9B34FB'; const HEART_RATE_MEASUREMENT_CHAR_UUID = '00002A37-0000-1000-8000-00805F9B34FB'; const enableHeartRateNotify = async (targetDeviceId) => { try { // 调用库内置方法开启通知,设置数据上报间隔为1000ms await BleManager.startNotification(targetDeviceId, HEART_RATE_SERVICE_UUID, HEART_RATE_MEASUREMENT_CHAR_UUID, 1000); } catch (error) { // 兜底逻辑:内置方法失效时,手动给CCC描述符写入通知使能值 const CCC_DESCRIPTOR_UUID = '00002902-0000-1000-8000-00805F9B34FB'; await BleManager.writeDescriptor( targetDeviceId, HEART_RATE_SERVICE_UUID, HEART_RATE_MEASUREMENT_CHAR_UUID, CCC_DESCRIPTOR_UUID, [0x01, 0x00] ); } }
3. 解析上报的心率数据
心率测量特征值的通用数据格式为:首字节为标志位,根据标志位判断心率值的存储格式:
- 标志位第0位为0时,心率值为1字节uint8类型
- 标志位第0位为1时,心率值为2字节小端序uint16类型
数据接收与解析代码:
import { useEffect } from 'react'; useEffect(() => { // 注册特征值数据更新监听 const notifyListener = BleManagerEmitter.addListener( 'BleManagerDidUpdateValueForCharacteristic', ({ value, peripheral, characteristic, service }) => { // 过滤匹配当前心率特征的上报数据 if ( peripheral.id === '你的手环设备ID' && characteristic.toUpperCase() === HEART_RATE_MEASUREMENT_CHAR_UUID.toUpperCase() && service.toUpperCase() === HEART_RATE_SERVICE_UUID.toUpperCase() ) { const flagByte = value[0]; let currentHeartRate; if ((flagByte & 0x01) === 0) { // 8位格式解析 currentHeartRate = value[1]; } else { // 16位小端序格式解析 currentHeartRate = value[1] + (value[2] << 8); } // 此处可将心率值存入组件state或全局状态 console.log('实时心率:', currentHeartRate); } } ); // 组件卸载时清理逻辑 return () => { notifyListener.remove(); // 主动关闭心率通知,避免后台功耗异常 BleManager.stopNotification( '你的手环设备ID', HEART_RATE_SERVICE_UUID, HEART_RATE_MEASUREMENT_CHAR_UUID ); }; }, []);
常见问题排查
- 安卓设备扫描不到手环:安卓11及以下系统需确保定位权限已授权,且位置信息开关处于开启状态
- 开启通知后无数据上报:检查UUID大小写是否匹配,部分厂商要求UUID全大写或全小写才能正常识别
- 解析数值异常:确认字节序是否符合设备要求,定制化设备需对照厂商提供的数据包格式调整解析逻辑
- 连接频繁断开:部分手环要求固定间隔下发心跳指令,需对照设备文档补充对应逻辑
内容的提问来源于stack exchange,提问作者Anderson
相关产品推荐
相关产品推荐

