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

如何用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:20:58