RxAndroidBle 2 先读取多个特征值再监听其他特征值通知的实现问题
RxAndroidBle 2 批量读取特征+开启CSC监听实现方案
第一步:定义待读取特征配置
提前配置你需要批量读取的最多12个特征的UUID和对应的解析逻辑,适配你需要返回的Int/String/Boolean类型值:
// 特征读取配置类,存储UUID和对应的字节解析规则 private static class ReadCharacteristicConfig { public final UUID uuid; public final Function<byte[], Object> parser; public ReadCharacteristicConfig(UUID uuid, Function<byte[], Object> parser) { this.uuid = uuid; this.parser = parser; } } // 初始化你的批量读取特征列表,按需添加最多12个配置 private final List<ReadCharacteristicConfig> BATCH_READ_CONFIGS = Arrays.asList( // 硬件版本特征:解析为字符串 new ReadCharacteristicConfig(Constants.DEVICE_HARDWARE, bytes -> ValueInterpreter.getStringValue(bytes, 0)), // 电池电量特征:解析为Int new ReadCharacteristicConfig(UUID.fromString("00002a19-0000-1000-8000-00805f9b34fb"), bytes -> ValueInterpreter.getIntValue(bytes, ValueInterpreter.FORMAT_UINT8, 0)), // 其他特征按需配置即可 // new ReadCharacteristicConfig(你的特征UUID, 对应的解析规则) );
第二步:整合批量读取与CSC监听逻辑
在原有连接逻辑基础上插入批量读取流程,保证先完成所有特征读取再开启CSC监听:
connectionSubscription = device.establishConnection(false) // 批量读取所有预设特征 .flatMapSingle(rxBleConnection -> Observable.fromIterable(BATCH_READ_CONFIGS) // 按顺序串行读取每个特征,符合BLE操作要求 .concatMapSingle(config -> rxBleConnection.readCharacteristic(config.uuid) // 读取完成后用预定义规则解析,封装为键值对 .map(bytes -> new AbstractMap.SimpleEntry<>(config.uuid, config.parser.apply(bytes))) // 可选配置:单个特征读取失败不中断整体流程,返回null占位 .onErrorReturnItem(new AbstractMap.SimpleEntry<>(config.uuid, null)) ) // 所有特征读取完成后收集为UUID到值的映射 .toMap(Map.Entry::getKey, Map.Entry::getValue) // 处理读取结果后将连接对象向下传递,供后续开启监听使用 .map(characteristicMap -> { // 此处可直接使用生成的映射结果,比如存储、打印 Log.d(TAG, "批量读取完成,共获取" + characteristicMap.size() + "个特征值"); return rxBleConnection; }) ) // 批量读取完成后开启CSC特征监听,和原有逻辑完全兼容 .flatMap(rxBleConnection -> rxBleConnection.setupNotification(Constants.CSC_MEASURE)) .doOnNext(notificationObservable -> { Log.d(TAG, "CSC监听注册完成: " + notificationObservable.toString()); }) .flatMap(notificationObservable -> notificationObservable) // 特征值变化回调沿用你原有解析逻辑即可 .subscribe( this::onCharacteristicChanged, throwable -> { if (throwable instanceof BleDisconnectedException) { Log.e(TAG, "设备断开连接: " + throwable.getClass().getCanonicalName()); } else { Log.e(TAG, "操作异常: ", throwable); } } );
可选配置说明
- 如果要求所有特征必须全部读取成功才能继续后续流程,删掉
onErrorReturnItem配置即可,任意特征读取失败会直接走错误回调 - 如果不需要保证特征读取顺序,可以把
concatMapSingle换成flatMapSingle提升读取速度
内容的提问来源于stack exchange,提问作者MBach
相关产品推荐
相关产品推荐

