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

Android如何连接已配对的Micro:Bit BBC设备并实现重连与特征读取

嗨,作为踩过不少BLE坑的Android开发者,太懂你现在的感受了——对着官方文档看半天,还是不知道从哪下手写代码!既然你已经能定位到配对好的Micro:Bit设备,那接下来的核心操作其实可以拆成三个关键环节,我给你一步步拆解,还补上你需要的核心代码片段:

第一步:建立BLE连接

首先,你手里应该已经有了配对设备对应的BluetoothDevice对象对吧?接下来要做的就是通过这个对象获取BluetoothGatt,并通过BluetoothGattCallback来监听所有连接、特征交互的状态。

先定义你的Gatt回调类,这是整个BLE交互的核心:

private val gattCallback = object : BluetoothGattCallback() {
    // 连接状态变化回调(成功/断开都会触发)
    override fun onConnectionStateChange(gatt: BluetoothGatt?, status: Int, newState: Int) {
        super.onConnectionStateChange(gatt, status, newState)
        when(newState) {
            BluetoothProfile.STATE_CONNECTED -> {
                // 连接成功!立刻开始发现设备的服务
                gatt?.discoverServices()
            }
            BluetoothProfile.STATE_DISCONNECTED -> {
                // 连接断开,这里可以处理重连逻辑
                handleReconnect(gatt)
            }
        }
    }

    // 服务发现完成回调
    override fun onServicesDiscovered(gatt: BluetoothGatt?, status: Int) {
        super.onServicesDiscovered(gatt, status)
        if (status == BluetoothGatt.GATT_SUCCESS) {
            // 服务发现成功,现在可以找你要读取的特征了
            findTargetCharacteristic(gatt)
        }
    }

    // 特征值读取完成回调
    override fun onCharacteristicRead(gatt: BluetoothGatt?, characteristic: BluetoothGattCharacteristic?, status: Int) {
        super.onCharacteristicRead(gatt, characteristic, status)
        if (status == BluetoothGatt.GATT_SUCCESS && characteristic != null) {
            // 这里拿到特征值,比如Micro:Bit的温度是小端字节序,需要转换
            val temperatureBytes = characteristic.value
            val temperature = ByteBuffer.wrap(temperatureBytes).order(ByteOrder.LITTLE_ENDIAN).short.toFloat() / 100f
            // 处理温度值,比如更新UI(注意要切回主线程)
            runOnUiThread {
                textViewTemperature.text = "当前温度:$temperature °C"
            }
        }
    }
}

然后发起连接:

// 假设device是你找到的配对Micro:Bit设备
val gatt = device.connectGatt(this, false, gattCallback)
// 第二个参数false表示不自动重连,如果需要后台自动重连可以设为true,但重连逻辑建议自己控制
第二步:实现断开后的自动重连

在上面的onConnectionStateChange回调里,当检测到STATE_DISCONNECTED时,你可以实现重连逻辑。这里要注意几个点:

  • 不要立刻发起重连,最好加个延迟(比如1-3秒),避免频繁重试消耗资源
  • 可以用Handler或者Coroutine来实现延迟重连
  • 如果是Android 12+,要确保你的APP有BLUETOOTH_CONNECT权限

重连的核心代码示例:

private fun handleReconnect(gatt: BluetoothGatt?) {
    // 先关闭旧的Gatt连接,避免内存泄漏
    gatt?.close()
    // 用Coroutine实现延迟重连(需要依赖kotlinx-coroutines-android)
    lifecycleScope.launch {
        delay(2000)
        // 重新发起连接,这里的device是你之前保存的配对设备对象
        device.connectGatt(this@MainActivity, false, gattCallback)
    }
}

另外,如果你希望APP在后台也能自动重连,可以考虑把connectGatt的第二个参数设为true(自动重连模式),但这种模式的重连时机由系统控制,灵活性不如自己实现的逻辑。

第三步:找到目标特征并读取值

Micro:Bit的BLE服务和特征都有固定的UUID,比如常见的环境温度特征,对应的服务UUID是E95D0753-251D-470A-A062-FA1922DFA9A8,特征UUID是E95D9250-251D-470A-A062-FA1922DFA9A8。你需要根据自己要读取的特征替换对应的UUID。

实现findTargetCharacteristic方法:

private fun findTargetCharacteristic(gatt: BluetoothGatt?) {
    gatt?.let {
        // 先找到对应的服务
        val environmentService = it.getService(UUID.fromString("E95D0753-251D-470A-A062-FA1922DFA9A8"))
        environmentService?.let { service ->
            // 找到目标特征
            val temperatureChar = service.getCharacteristic(UUID.fromString("E95D9250-251D-470A-A062-FA1922DFA9A8"))
            temperatureChar?.let { char ->
                // 读取特征值,注意BLE操作必须在子线程,这里connectGatt已经在子线程处理了,但保险起见可以确认
                it.readCharacteristic(char)
            }
        }
    }
}
几个新手必注意的坑
  • 权限问题:Android 12+需要申请BLUETOOTH_SCAN、BLUETOOTH_CONNECT权限,Android 11及以下需要ACCESS_FINE_LOCATION权限才能扫描设备(你已经配对了设备,可能不需要扫描,但连接还是要对应权限)
  • 主线程限制:所有BLE操作(连接、读写特征)都不能在主线程执行,BluetoothGatt的回调默认在Binder线程,所以更新UI一定要切回主线程
  • 资源释放:当不再需要连接时,一定要调用gatt.close(),避免内存泄漏和占用BLE资源
  • UUID大小写:Micro:Bit的UUID是小写的,注意不要写错大小写

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 08:18:43