Android Kotlin中UUID转16位及蓝牙扫描过滤器多ID配置问题
问题解决指南
1. 错误原因分析
- 第一个错误:
0x1810和0x2A35是16位整数,而byteArrayOf要求的是8位Byte类型(范围-128~127),数值超出范围导致报错。另外你误用了setServiceData方法,该方法用于过滤广播中的服务数据字段,而非服务UUID本身。 - 第二个错误:
setServiceUuid方法要求传入ParcelUuid类型参数,你传入ByteArray和String,类型不匹配。
2. 16位UUID转ParcelUuid的正确方式
蓝牙规范中,16位UUID是基于基础UUID的简写,完整格式为:0000XXXX-0000-1000-8000-00805F9B34FB,只需将16位UUID替换到XXXX位置即可。转换步骤:
- 用
UUID.fromString()生成完整UUID对象 - 用
ParcelUuid.fromUuid()转为ParcelUuid类型
示例:
// 血压服务16位UUID 0x1810转ParcelUuid val bloodPressureServiceUuid = UUID.fromString("00001810-0000-1000-8000-00805F9B34FB") val parcelBloodPressureService = ParcelUuid.fromUuid(bloodPressureServiceUuid) // 血压测量特征16位UUID 0x2A35转ParcelUuid val bloodPressureMeasurementUuid = UUID.fromString("00002A35-0000-1000-8000-00805F9B34FB") val parcelBloodPressureMeasurement = ParcelUuid.fromUuid(bloodPressureMeasurementUuid)
3. 配置包含多个UUID的扫描过滤器
如果你想扫描支持任一指定UUID的设备,可使用setServiceUuids方法传入ParcelUuid列表;如果需要更精准的匹配(比如同时包含多个服务),可以配合掩码使用。
修正后的完整代码:
private fun scanFilters(): List<ScanFilter> { // 1. 转换16位UUID为ParcelUuid val bloodPressureServiceParcel = ParcelUuid.fromUuid( UUID.fromString("00001810-0000-1000-8000-00805F9B34FB") ) val bloodPressureMeasurementParcel = ParcelUuid.fromUuid( UUID.fromString("00002A35-0000-1000-8000-00805F9B34FB") ) // 2. 构建扫描过滤器,匹配任一指定UUID的设备 val scanFilter = ScanFilter.Builder() .setServiceUuids(listOf(bloodPressureServiceParcel, bloodPressureMeasurementParcel)) // 如果需要精准匹配,可添加掩码(可选) // .setServiceUuidMask(ParcelUuid.fromUuid(UUID.fromString("FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF"))) .build() return listOf(scanFilter) }
补充说明
- 如果你的需求是过滤同时包含两个服务的设备,需要分别设置每个UUID的掩码,或者创建多个过滤器组合使用(具体取决于蓝牙广播的结构)。
setServiceData方法适用于过滤广播中携带的自定义服务数据,比如设备发送的特定字节数据,不是用来过滤服务UUID的。
内容的提问来源于stack exchange,提问作者Compose Learner
相关产品推荐
相关产品推荐

