You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

蓝牙手表无心率/步数服务,RxAndroidBle读取特征值失败求助

解决蓝牙手表心率/步数数据获取问题

核心问题分析

你遇到的Characteristic not found错误,说明你的手表没有使用蓝牙标准心率特征UUID(0x2A37),大概率是厂商自定义了服务/特征UUID。另外,心率数据通常是通过订阅特征通知获取,而非单次读取,这也是你现有代码的误区。

步骤1:先扫描设备所有服务与特征

先不要直接指定UUID读取,先连接后发现所有服务和特征,确认手表实际支持的服务:

start.setOnClickListener(v -> {
    connectionDisposable = device.establishConnection(false)
            .flatMap(rxBleConnection -> rxBleConnection.discoverServices()
                    .flatMapObservable(rxBleDeviceServices -> {
                        // 遍历所有服务
                        for (RxBleService service : rxBleDeviceServices.getServices()) {
                            UUID serviceUuid = service.getUuid();
                            System.out.println("发现服务: " + serviceUuid);
                            // 遍历该服务下所有特征
                            for (RxBleCharacteristic characteristic : service.getCharacteristics()) {
                                UUID charUuid = characteristic.getUuid();
                                // 打印特征UUID和属性(判断是否支持notify/indicate)
                                System.out.println("  特征UUID: " + charUuid + ", 属性: " + characteristic.getProperties());
                            }
                        }
                        return Observable.empty();
                    })
            )
            .subscribe(
                    () -> {},
                    throwable -> System.out.println("错误: " + throwable.getMessage())
            );
});

运行这段代码,查看日志里的服务和特征列表,找到和心率/步数相关的自定义UUID(通常厂商会在UUID里包含相关标识,比如"heart"、"step"或特定数字)。

步骤2:订阅目标特征的通知

一旦找到对应特征,判断其属性是否包含PROPERTY_NOTIFY或PROPERTY_INDICATE(运动数据几乎都是通知方式推送),然后订阅通知:

// 替换为你找到的自定义心率/步数特征UUID
UUID targetCharUuid = UUID.fromString("这里填你找到的特征UUID");

start.setOnClickListener(v -> {
    connectionDisposable = device.establishConnection(false)
            .flatMap(rxBleConnection -> rxBleConnection.setupNotification(targetCharUuid)
                    .flatMap(notificationObservable -> notificationObservable)
            )
            .subscribe(
                    data -> {
                        // 解析收到的二进制数据(厂商自定义格式,需要参考手表的BLE协议文档)
                        String hexData = byteArrayToHex(data);
                        System.out.println("收到数据: " + hexData);
                        // 示例:如果是标准心率格式,解析方式如下(如果是自定义格式需要调整)
                        // int heartRate = data[1] & 0xFF;
                        // System.out.println("心率: " + heartRate);
                    },
                    throwable -> System.out.println("订阅错误: " + throwable.getMessage())
            );
});

步骤3:关键注意事项

  • 权限检查:确保已申请BLUETOOTH_CONNECT、BLUETOOTH_SCAN权限(Android 12及以上),并在运行时动态申请。
  • 不要过早断开连接:你现有代码用Handler 10秒后断开连接,可能还没收到数据,建议在页面销毁时再调用connectionDisposable.dispose()。
  • 协议文档:如果找不到特征对应的解析方式,需要联系手表厂商获取BLE通信协议文档,自定义设备的数据格式没有统一标准。

替代方案

如果上述方法仍无法获取数据,可以尝试:

  • 使用Android原生BLE API(而非RxAndroidBle),直接实现连接、发现服务、订阅通知的流程,排查是否是库的适配问题。
  • 用nRF Connect工具手动连接手表,尝试订阅可疑特征,查看是否能收到数据,验证特征的有效性。

内容的提问来源于stack exchange,提问作者Azarudeen Asraff

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 21:03:31