如何用RxAndroidBLE转Rx模式,响应BLE特征通知并发送写入命令
嘿,我之前在项目里也折腾过把传统BLE回调转成RxAndroidBLE的模式,尤其是这种需要循环交互的场景,踩过一些坑,给你分享下我的解决方案!
先理清楚核心逻辑
其实Rx的思路就是把通知接收和命令写入变成一个连贯的数据流,而不是用回调打断代码逻辑。你要做的就是把「收到通知→解析数据→发对应命令→等待下一个通知」这个循环变成可订阅的Observable流,让Rx帮你处理异步和线程调度。
具体代码实现示例
我用Kotlin写个核心流程的示例,你可以根据自己的Java/Kotlin项目调整:
首先,先建立BLE连接(记得提前处理权限、设备状态这些前置条件):
val rxBleClient = RxBleClient.create(context) val targetDevice = rxBleClient.getBleDevice("你的设备MAC地址") // 建立连接,false表示不自动重连(可根据需求改成true) val connectionFlow = targetDevice.establishConnection(false)
然后构建通知+写入的循环流:
connectionFlow .flatMap { connection -> // 第一步:开启目标特征的通知 connection.setupNotification(UUID.fromString("你的自定义特征UUID")) .flatMap { notificationFlow -> // 第二步:监听通知数据,解析后决定要发送的命令 notificationFlow .map { receivedBytes -> // 这里写你的数据解析逻辑,把字节数组转成业务模型 parseBleData(receivedBytes) } // 用concatMap保证每次写入串行执行,避免BLE并发操作报错 .concatMap { parsedData -> // 根据解析结果生成对应的写入命令字节数组 val commandBytes = when (parsedData) { is DeviceData.TypeX -> getXCommandBytes() is DeviceData.TypeY -> getYCommandBytes() else -> getDefaultCommandBytes() } // 第三步:发送命令,写入完成后继续监听下一个通知 connection.writeCharacteristic( UUID.fromString("你的自定义特征UUID"), commandBytes ) // 把解析后的数据传递下去,方便后续处理(比如日志、UI更新) .map { parsedData } } } } // 切换到主线程处理结果(如果需要更新UI的话) .observeOn(AndroidSchedulers.mainThread()) .subscribe( { processedData -> // 处理每一轮交互完成后的逻辑,比如更新UI日志 Log.d("BLE交互", "完成一轮命令响应: $processedData") }, { error -> // 处理错误,比如连接断开、写入失败等 Log.e("BLE错误", "交互出错", error) // 可在这里添加重连逻辑,或者提示用户 } )
几个关键注意点
- 资源释放:一定要在页面销毁或不再需要BLE交互时,调用订阅的
dispose()方法,断开连接并释放资源,不然会导致内存泄漏或BLE栈异常。 - 初始命令触发:如果设备需要先发送初始命令才会推送通知,可在连接成功后先执行写入操作,再开启通知:
connectionFlow .flatMap { connection -> connection.writeCharacteristic(initialCommandUuid, initialCommandBytes) .andThen(connection.setupNotification(notificationUuid)) // ... 后面的逻辑不变 } - 线程调度:RxAndroidBLE的BLE操作默认在IO线程执行,更新UI一定要用
observeOn(AndroidSchedulers.mainThread())切换线程。 - 错误处理:要考虑连接超时、设备断开、写入失败等异常,可在错误回调里处理,或用
retryWhen实现重连逻辑。
这样整个流程就是Rx的链式调用,再也不用写一堆嵌套回调,逻辑清晰很多!
内容的提问来源于stack exchange,提问作者Peter
相关产品推荐
相关产品推荐

