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

调用readCharacteristic后BLE的onCharacteristicRead回调未触发求助

解决BLE特征读取成功但onCharacteristicRead回调不触发的问题

以下是针对你遇到的问题的排查方向和解决方案:

1. 检查onCharacteristicRead的方法签名

Android BLE回调在不同API版本中有参数差异:

  • API 33及以上,回调方法新增value: ByteArray参数
  • API 33以下,方法无value参数,需从characteristic.getValue()获取数据

如果你的应用兼容低版本系统,或测试设备系统版本低于API 33,系统会调用不带value的旧版方法,而你未重写该方法就会导致回调无法触发。建议同时兼容两个版本的回调:

private val gattCallback = object: BluetoothGattCallback() {
    // 兼容API 33+
    override fun onCharacteristicRead(
        gatt: BluetoothGatt,
        characteristic: BluetoothGattCharacteristic,
        value: ByteArray,
        status: Int
    ) {
        handleReadResult(gatt, characteristic, value, status)
    }

    // 兼容API 33以下
    override fun onCharacteristicRead(
        gatt: BluetoothGatt?,
        characteristic: BluetoothGattCharacteristic?,
        status: Int
    ) {
        gatt?.let { g ->
            characteristic?.let { c ->
                handleReadResult(g, c, c.value ?: byteArrayOf(), status)
            }
        }
    }

    private fun handleReadResult(
        gatt: BluetoothGatt,
        characteristic: BluetoothGattCharacteristic,
        value: ByteArray,
        status: Int
    ) {
        Log.i("Callback", "onCharacteristicRead")
        with(characteristic) {
            when (status) {
                BluetoothGatt.GATT_SUCCESS -> {
                    Log.i("BluetoothGattCallback", "Read characteristic $uuid:\n${value.toHexString()}")
                }
                BluetoothGatt.GATT_READ_NOT_PERMITTED -> {
                    Log.e("BluetoothGattCallback", "Read not permitted for $uuid!")
                }
                else -> {
                    Log.e("BluetoothGattCallback", "Characteristic read failed for $uuid, error: $status")
                }
            }
        }
    }
}

2. 确认特征对象与当前Gatt实例匹配

确保lpnInfoChar是从当前连接的btGatt实例中获取的,而非旧连接缓存的对象。每次重新连接后,需在onServicesDiscovered回调中重新获取服务和特征:

override fun onServicesDiscovered(gatt: BluetoothGatt?, status: Int) {
    super.onServicesDiscovered(gatt, status)
    if (status == BluetoothGatt.GATT_SUCCESS) {
        val targetService = gatt?.getService(UUID.fromString("你的自定义服务UUID"))
        lpnInfoChar = targetService?.getCharacteristic(UUID.fromString("你的自定义特征UUID"))
    }
}

3. 重置BLE连接

有时Android系统的BLE操作队列会出现隐性阻塞,即便无可见未处理请求。可尝试断开并重新连接后再读取:

fun resetConnectionAndRead() {
    btGatt?.let { gatt ->
        gatt.disconnect()
        gatt.close()
    }
    // 重新扫描连接设备,完成后调用readOneSpecificCharacteristic()
}

4. 取消特征通知(若已订阅)

部分BLE设备在特征被订阅通知后,会优先响应通知而非读取请求。可先取消通知再尝试读取:

fun cancelNotifyAndRead() {
    btGatt?.setCharacteristicNotification(lpnInfoChar, false)
    val descriptor = lpnInfoChar?.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"))
    descriptor?.let { desc ->
        desc.value = BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE
        btGatt?.writeDescriptor(desc)
    }
    // 等待Descriptor写入完成后,调用readOneSpecificCharacteristic()
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 22:00:23