Android 12+ BLE 字节不同

问题描述 投票:0回答:1

我在 Kotlin 中开发了一个小应用程序,它使用 bluetoothLeScanner.startScan(scanCallback) 扫描附近的

BLE
-信标。 这非常有效(扫描/发现部分)。

Android 10Android 12Android 13上测试我的应用程序后,我发现,

ScanResult.scanRecord.bytes
数组对于相同的BLE-Beacon(相同的设备名称和相同的设备MAC地址)完全不同)在 Android 12Android 13
我可以完全访问 Android 10 中的“正确”字节,这使我能够读取 MajorMinor、*UUID *和 自定义添加 BatteryLevel。 BatteryLevel 只是一个额外的字节,范围从 00 到 64(00 = 0% 和 64 = 100%)。
Android 12+中,我得到一个字节数组,其中仅包含MAC地址(这是我在将每个字节转换为十六进制后可以计算出的)。存在的字节数比 MAC 地址多,但这些对我来说是未知的(提到的字节与 UUID、主要、次要或电池电量不同)。

所以基本上我的问题是从 Android 12+ 获取与从 Android 10 获取的数据量相同的数据。这就是为什么我猜测需要调整

bluetoothLeScanner.startScan(scanCallback)
才能使 Android 12+ 正常工作,或者我需要更改我为 Android 12+ 收集每个
ScanResult
的数据的方式。

我将不胜感激任何形式的帮助。

我查看了 Android BLE 文档,但没有任何地方写到

ScanResult.scanRecord.bytes
数组从 Android 12 开始发生变化。除了需要为 Android 12+ 设置的 蓝牙权限 之外,也没有提及针对 Android 12+ 的任何不同方法。

我查看了字节数组,将其转换为十六进制,并搜索模式(如果要找到 UUID、Major、Minor 或 BatteryLevel),不幸的是没有结果。在 YT 上搜索 BLE 教程也没有帮助。 Android 11 及以下版本上主要有理论视频或 BLE 视频。

BLE 信标扫描代码:

bluetoothLeScanner.startScan(scanCallback)

Android 清单权限

<!-- Request legacy Bluetooth permissions on older devices. -->
    <uses-permission android:name="android.permission.BLUETOOTH"
        android:maxSdkVersion="30" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"
        android:maxSdkVersion="30" />

    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />

    <!-- Include "neverForLocation" only if you can strongly assert that
         your app never derives physical location from Bluetooth scan results. -->
    <uses-permission android:name="android.permission.BLUETOOTH_SCAN"
        android:usesPermissionFlags="neverForLocation" />

    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" android:maxSdkVersion="30" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" android:maxSdkVersion="30" />
    <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" android:maxSdkVersion="30"/>

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
        android:maxSdkVersion="32" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
        android:maxSdkVersion="32" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

    <uses-feature android:name="android.hardware.bluetooth" android:required="true"/>
    <uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>

ScanCallback onScanResult
内的代码:

if(result.scanRecord?.bytes != null){
val sb = StringBuilder()
for (b in result.scanRecord!!.bytes) {
sb.append(String.format("%02X", b))
}
val trimmedSb = sb.toString().trim()  
if(trimmedSb.endsWith("000000000000000000000000000000000000000000000000000000000000"))  {  
return // useless data  
}  


if(trimmedSb.length >= 61){  
  if(trimmedSb.endsWith("0000")){  
     batteryLevel = -1  
  }else{  
     batteryLevel = trimmedSb.substring(IntRange(60, 61)).toInt(16)  
  }  
}  

if(trimmedSb.length >= 50){
val uuid_first = trimmedSb.substring(18,26)
val uuid_second = trimmedSb.substring(26, 30) 
val uuid_third = trimmedSb.substring(30,34)
val uuid_fourth = trimmedSb.substring(34, 38)  
val uuid_fith = trimmedSb.substring(38,50)      
uuid = "$uuid_first-$uuid_second-$uuid_third-$uuid_fourth-$uuid_fith"  
}

if(trimmedSb.length >= 54){
major = trimmedSb.substring(50, 54).padStart(4,'0')
}

if(trimmedSb.length >= 58){
minor = trimmedSb.substring(54, 58).padStart(4,'0')
}
android kotlin bluetooth-lowenergy android-bluetooth
1个回答
0
投票

通过断言扫描是“neverForLocation”,您表示您并不是在寻找信标设备。对于扫描信标设备,您不应添加“neverForLocation”属性,而是需要在清单中添加位置权限并打开位置。

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.