Android13 BLE扫描不到设备啦

客户又急吼吼的来找我们:大事不好啦!Android13扫不到蓝牙设备了!

国外新系统出的早,国内没有真机实测,开发者也挺憋屈,还要被客户说不专业,经过一番搜索研究,近期出现问题的多是三星S22Ultra,升级到Android13后,搜索不到蓝牙设备了。

Android13在BLE这块新增和改动还是挺多的,其中导致“搜索不到设备”的原因,很可能是APP过滤设备名称,但是 ScanResult 获取的名字是 null,关键就在于设备的名字是不是放在了扫描回应包,如果是,那恭喜,你们的产品遇上麻烦了!Android13以前,广播的原始数据也是62字节,但广播包跟扫描回应包是连一起的,而Android13,把扫描回应包放在了后面的31字节中,也就是广播包和扫描回应包之间有很多0,导致 ScanRecord 没有 deviceName,但是Android13又没有提供针对扫描回应包的类或者接口,那这种情况就需要写代码补救,这怎么看都不像是Android的设计方式,但现实就是这样,既然碰上了这种问题,那就还是要处理,下面是相关代码

class ScanResponse {
    var localName: String? = null
}

fun parseName(scanResult: ScanResult): String? {
    if (Build.VERSION.SDK_INT >= 33) {
        //Android13
        scanResult.scanRecord?.let { scanRecord ->
            if (scanRecord.deviceName != null) {
                return scanRecord.deviceName
            } else {
                //deviceName为空再去解析扫描回应包,这样兼容性好一些
                scanRecord.bytes?.let { rawBytes ->
                    //rawBytes 总长度62字节,前半部分是31字节的广播包数据,后半部分是31字节的扫描回应包数据
                    val scanResponse = parseScanResponse(rawBytes, 31)
                    return scanResponse.localName
                }
            }
        }
    }

    return scanResult.scanRecord?.deviceName
}

@TargetApi(33)
fun parseScanResponse(bytes: ByteArray, start: Int): ScanResponse {
    val scanResponse = ScanResponse()
    var pos = start
    var len = bytes[pos].toInt().and(0xff)
    var dataType: Int
    var data: ByteArray
    while (len > 0) {
        dataType = bytes[++pos].toInt().and(0xff)
        data = bytes.copyOfRange(pos, pos + len - 1)
        when (dataType) {
            ScanRecord.DATA_TYPE_LOCAL_NAME_SHORT,
            ScanRecord.DATA_TYPE_LOCAL_NAME_COMPLETE -> {
                val localName = String(data)
                println("localName: $localName")
                scanResponse.localName = localName
            }
            //如果还需要解析其他数据,添加其他 DATA_TYPE_xxx 即可
            else -> {
                println("Data Type: 0x${String.format("%02X", dataType)}, Data: $data")
            }
        }
        pos += len - 1
        len = bytes[pos].toInt().and(0xff)
    }
    return scanResponse
}

你可能感兴趣的:(android,开发语言)