安卓Kotlin BLE开发:如何通过UUID识别设备可用服务与可读内容
BLE设备广播内容与特征数据识别实现方案(Kotlin安卓方向)
读取广播包内容(无需连接设备即可获取)
BLE设备的广播内容在扫描阶段就可以直接获取,不需要建立GATT连接,通过ScanCallback的回调参数即可解析:
private val bleScanCallback = object : ScanCallback() { override fun onScanResult(callbackType: Int, result: ScanResult?) { super.onScanResult(callbackType, result) result ?: return val scanRecord = result.scanRecord ?: return // 可直接获取的广播字段 val deviceName = scanRecord.deviceName val rssi = result.rssi // 信号强度 val broadcastServiceUuids = scanRecord.serviceUuids // 广播携带的服务UUID val rawBroadcastBytes = scanRecord.bytes // 广播原始字节数组 // 打印示例 val rawHex = rawBroadcastBytes.joinToString(" ") { "%02X".format(it) } Log.d("BLE广播", "设备名:$deviceName 信号强度:$rssi 原始广播数据:$rawHex") } }
读取已连接设备的特征数据
建立GATT连接并发现服务后,先判断特征的可读权限,再执行读取操作,最后根据UUID类型解析数值:
第一步:判断特征可读权限并发起读取
// 遍历所有服务和特征 gatt.services.forEach { service -> service.characteristics.forEach { characteristic -> // 检查特征是否支持读取 val canRead = (characteristic.properties and BluetoothGattCharacteristic.PROPERTY_READ) != 0 if (canRead) { // 发起读取请求,注意不要并发发起多个读取请求,等上一个回调完成再发下一个 gatt.readCharacteristic(characteristic) } } }
第二步:在读取回调中解析数据
override fun onCharacteristicRead( gatt: BluetoothGatt?, characteristic: BluetoothGattCharacteristic?, status: Int ) { super.onCharacteristicRead(gatt, characteristic, status) if (status != BluetoothGatt.GATT_SUCCESS || characteristic == null) return val rawValue = characteristic.value // 标准UUID特征按照蓝牙联盟规范解析,厂商自定义UUID需对应厂商协议解析 when (characteristic.uuid.toString()) { "00002a19-0000-1000-8000-00805f9b34fb" -> { // 电池电量特征,单字节0-100 val batteryPercent = rawValue[0].toInt() Log.d("特征解析", "电池电量:$batteryPercent%") } "00002a2b-0000-1000-8000-00805f9b34fb" -> { // 当前时间特征,按蓝牙时间规范解析 val year = (rawValue[1].toInt() shl 8) or rawValue[0].toInt() val month = rawValue[2].toInt() val day = rawValue[3].toInt() Log.d("特征解析", "当前时间:$year年$month月$day日") } else -> { // 未知特征先打印原始十六进制值 val hexValue = rawValue.joinToString(" ") { "%02X".format(it) } Log.d("特征解析", "UUID:${characteristic.uuid} 原始值:$hexValue") } } }
你提供的Gatt表快速识别
UUID前缀为0000xxxx-0000-1000-8000-00805f9b34fb的是蓝牙联盟定义的标准公开服务/特征,其他为厂商自定义私有内容:
- 00001801服务:通用属性服务,对应00002a05特征为服务修改通知特征
- d0611e78服务:厂商自定义私有服务,对应8667556c为私有特征,需设备厂商提供协议解析
- 9fa480e0服务:厂商自定义私有服务,对应af0badb1为私有特征,需设备厂商提供协议解析
- 0000180f服务:标准电池服务,对应00002a19为电池电量特征
- 00001805服务:标准当前时间服务,对应00002a2b为当前时间特征、00002a0f为本地时间信息特征
注意事项
- 安卓12及以上系统需要动态申请
BLUETOOTH_SCAN、BLUETOOTH_CONNECT权限才能执行扫描、连接、读特征操作 - 不要同时发起多个GATT操作,所有读取、写入、通知操作都要等上一个操作的回调返回后再发起下一个,避免出现协议栈错误
- 私有厂商UUID的特征如果没有对应协议文档,只能获取原始字节,无法直接解析为可读业务内容
内容的提问来源于stack exchange,提问作者Prabh Singh
相关产品推荐
相关产品推荐

