客户又急吼吼的来找我们:大事不好啦!Android13扫不到蓝牙设备了!
国外新系统出的早,国内没有真机实测,开发者也挺憋屈,还要被客户说不专业,经过一番搜索研究,近期出现问题的多是三星S22Ultra,升级到Android13后,搜索不到蓝牙设备了。文章来源:https://www.toymoban.com/news/detail-519858.html
Android13在BLE这块新增和改动还是挺多的,其中导致“搜索不到设备”的原因,很可能是APP过滤设备名称,但是 ScanResult 获取的名字是 null,关键就在于设备的名字是不是放在了扫描回应包,如果是,那恭喜,你们的产品遇上麻烦了!Android13以前,广播的原始数据也是62字节,但广播包跟扫描回应包是连一起的,而Android13,把扫描回应包放在了后面的31字节中,也就是广播包和扫描回应包之间有很多0,导致 ScanRecord 没有 deviceName,但是Android13又没有提供针对扫描回应包的类或者接口,那这种情况就需要写代码补救,这怎么看都不像是Android的设计方式,但现实就是这样,既然碰上了这种问题,那就还是要处理,下面是相关代码文章来源地址https://www.toymoban.com/news/detail-519858.html
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
}
到了这里,关于Android13 BLE扫描不到设备啦的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!