如何通过UUID实现与简易BLE蓝牙按钮的成功通信
BLE自拍按钮与APP通信问题:通知无法激活
- 设备可正常配对连接,但代码实现通信时通知设置始终失效
- 已完成设备发现与MAC地址连接,通过第三方BLE应用获取了疑似UUID,但遍历所有UUID均无法激活按钮按压通知
- 使用RxAndroidBle3库开发,尝试通过写入人机接口特征的CCCD来开启通知,无效果
现有实现代码
package com.example.androidcounterapp import android.annotation.SuppressLint import android.bluetooth.BluetoothAdapter import android.bluetooth.BluetoothGattDescriptor import android.content.ContentValues.TAG import android.content.Context import android.util.Log import com.polidea.rxandroidble3.RxBleClient import com.polidea.rxandroidble3.RxBleDevice import io.reactivex.rxjava3.disposables.Disposable import java.util.UUID class BluetoothConnection { val serviceUuidUUID = UUID.fromString("00001812-0000-1000-8000-00805f9b34fb") val characteristicUUID = UUID.fromString("00002a4d-0000-1000-8000-00805f9b34fb") val cccdUUID = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb") inner class ConnectThread( private val context: Context, private val macAddress: String, private val bluetoothAdapter: BluetoothAdapter ) : Thread() { private val rxBleClient: RxBleClient by lazy(LazyThreadSafetyMode.NONE) { RxBleClient.create(context) } private var connectionDisposable: Disposable? = null @SuppressLint("MissingPermission") private fun connectAndSetupNotification( device: RxBleDevice, characteristicUUID: UUID, cccdUUID: UUID, ) { Log.i(TAG, "Entered connectAndSetupNotification") connectionDisposable = device.establishConnection(false) .flatMap { rxBleConnection -> Log.i(TAG, "GATT connection established") rxBleConnection.setupNotification(characteristicUUID) .flatMap { notificationObservable -> val enableNotificationValue = BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE val descriptor = BluetoothGattDescriptor( cccdUUID, BluetoothGattDescriptor.PERMISSION_WRITE ).apply { value = enableNotificationValue } rxBleConnection.writeDescriptor(descriptor, enableNotificationValue) .andThen(notificationObservable) } } .subscribe( { notificationData -> Log.i(TAG, "Notification data: ${notificationData.joinToString(", ")}") val readableValue = CharacteristicConverter.convert(notificationData) Log.i(TAG, "Readable value: $readableValue") }, { throwable -> Log.e(TAG, "Error occurred while setting up notification", throwable) } ) } @SuppressLint("MissingPermission") override fun run() { bluetoothAdapter.cancelDiscovery() Log.i(TAG, "Trying to connect") val device = rxBleClient.getBleDevice(macAddress) connectAndSetupNotification(device, characteristicUUID, cccdUUID) } fun cancel() { connectionDisposable?.dispose() } } }
排查与修复建议
1. 修正RxAndroidBle通知设置逻辑
RxAndroidBle的setupNotification()方法已经内置了CCCD写入逻辑,无需手动创建Descriptor并写入,重复操作可能导致冲突。简化后的代码:
@SuppressLint("MissingPermission") private fun connectAndSetupNotification( device: RxBleDevice, characteristicUUID: UUID, ) { Log.i(TAG, "Entered connectAndSetupNotification") connectionDisposable = device.establishConnection(false) .flatMap { rxBleConnection -> Log.i(TAG, "GATT connection established") // 直接调用setupNotification,内部自动处理CCCD写入 rxBleConnection.setupNotification(characteristicUUID) .flatMap { it } } .subscribe( { notificationData -> Log.i(TAG, "Notification data: ${notificationData.joinToString(", ")}") val readableValue = CharacteristicConverter.convert(notificationData) Log.i(TAG, "Readable value: $readableValue") }, { throwable -> Log.e(TAG, "Error occurred while setting up notification", throwable) } ) }
2. 确认目标特征的属性
用BLE调试工具(如nRF Connect)查看设备的特征属性:
- 确认目标特征支持Notify或Indicate属性
- 定位按钮按压事件对应的特征(通常是按钮按下时主动发送数据的可通知特征)
3. 遍历所有服务与特征排查
由于设备无文档,连接成功后遍历所有服务和特征,打印UUID并逐个测试通知:
@SuppressLint("MissingPermission") private fun discoverAllServicesAndCharacteristics(device: RxBleDevice) { device.establishConnection(false) .flatMapSingle { it.discoverServices() } .subscribe( { services -> services.forEach { service -> Log.i(TAG, "Service UUID: ${service.uuid}") service.characteristics.forEach { characteristic -> val hasNotify = (characteristic.properties and BluetoothGattCharacteristic.PROPERTY_NOTIFY) != 0 Log.i(TAG, "Characteristic UUID: ${characteristic.uuid}, Support Notify: $hasNotify") // 对支持Notify的特征逐个测试 if (hasNotify) { connectAndSetupNotification(device, characteristic.uuid) } } } }, { throwable -> Log.e(TAG, "Discover services error", throwable) } ) }
4. 检查权限与连接参数
- Android 12+需确保已申请
BLUETOOTH_CONNECT、BLUETOOTH_SCAN权限 - 连接时可尝试设置
autoConnect = true,提升连接稳定性:device.establishConnection(true)
内容的提问来源于stack exchange,提问作者Christian
相关产品推荐
相关产品推荐

