Bluetooth LE ScanResult 返回 null,但我知道我的外围设备正在广播心率服务 UUID(由第 3 方 BLE 应用程序验证)。为什么?
Bluetooth LE ScanResult is returning null, but I know my peripheral is broadcasting a heart rate Service UUID (as verified by 3rd-party BLE app). Why?
我对 BLE 扫描没有返回 GATT 服务 UUID(即 scanRecord.getServiceUUIDs()
returns null
)感到沮丧。但是,我知道我的心率外围设备正在正常工作和广告,因为心率服务已被 LightBlue 应用程序发现(并且可读)。
这是我的 ScanCallback
对象中的函数:
override fun onScanResult(callbackType: Int, result: ScanResult?) {
super.onScanResult(callbackType, result)
// This log shows that result.mServiceUuids is null
Log.i(TAG, "BLEDeviceManager.ScanCallback.onScanResult: ${result.toString()}")
// TODO: handle null ScanResult
val parcelUuids = if (result.getScanRecord() != null) result.getScanRecord()!!.getServiceUuids() else null
if (parcelUuids == null) {
Log.i(TAG, "parcelUUids was null for scanRecord = ${result.getScanRecord()!!.toString()}")
return
}
val serviceList = ArrayList<UUID>()
for (i in parcelUuids.indices) {
val serviceUUID = parcelUuids.get(i).getUuid()
if (!serviceList.contains(serviceUUID))
serviceList.add(serviceUUID)
}
Log.i(TAG, "Here is a list of the service UUIDs: $serviceList")
}
这是日志:
I/BLEDeviceManager: parcelUUids was null for scanRecord = ScanRecord [mAdvertiseFlags=6, mServiceUuids=null, mServiceSolicitationUuids=null, mManufacturerSpecificData={}, mServiceData={}, mTxPowerLevel=3, mDeviceName=blehr_sensor_1.0]
我做错了什么,mServiceUuids
总是空的?
根据您输出的 ScanRecord,您的设备没有发布任何服务 UUID。这并不意味着它没有该服务....它只是不做广告。
您可能想要连接到它,然后调用 discoverServices() 以获取它真正拥有的服务列表...
可能是您的设备公布了无效数据。如果是这样,Android 将 return 一个空的服务列表,即使无效数据位于不相关的字段中也是如此。
所以分析广告数据并检查它是否有你要找的UUID。一旦你明白这是怎么回事,你就可以自己解析数据了。
(以下代码是 Java 而不是 Kotlin。但是 Android Studio 应该会自动转换它。)
@Override
public void onScanResult(int callbackType, ScanResult result) {
super.onScanResult(callbackType, result);
ScanRecord scanRecord = result.getScanRecord();
byte[] advertisementData = scanRecord.getBytes();
Log.i(TAG, "advertisement data: " + bytesToHex(advertisementData));
}
private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
public static String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
for (int j = 0; j < bytes.length; j++) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = HEX_ARRAY[v >>> 4];
hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
}
return new String(hexChars);
}
我对 BLE 扫描没有返回 GATT 服务 UUID(即 scanRecord.getServiceUUIDs()
returns null
)感到沮丧。但是,我知道我的心率外围设备正在正常工作和广告,因为心率服务已被 LightBlue 应用程序发现(并且可读)。
这是我的 ScanCallback
对象中的函数:
override fun onScanResult(callbackType: Int, result: ScanResult?) {
super.onScanResult(callbackType, result)
// This log shows that result.mServiceUuids is null
Log.i(TAG, "BLEDeviceManager.ScanCallback.onScanResult: ${result.toString()}")
// TODO: handle null ScanResult
val parcelUuids = if (result.getScanRecord() != null) result.getScanRecord()!!.getServiceUuids() else null
if (parcelUuids == null) {
Log.i(TAG, "parcelUUids was null for scanRecord = ${result.getScanRecord()!!.toString()}")
return
}
val serviceList = ArrayList<UUID>()
for (i in parcelUuids.indices) {
val serviceUUID = parcelUuids.get(i).getUuid()
if (!serviceList.contains(serviceUUID))
serviceList.add(serviceUUID)
}
Log.i(TAG, "Here is a list of the service UUIDs: $serviceList")
}
这是日志:
I/BLEDeviceManager: parcelUUids was null for scanRecord = ScanRecord [mAdvertiseFlags=6, mServiceUuids=null, mServiceSolicitationUuids=null, mManufacturerSpecificData={}, mServiceData={}, mTxPowerLevel=3, mDeviceName=blehr_sensor_1.0]
我做错了什么,mServiceUuids
总是空的?
根据您输出的 ScanRecord,您的设备没有发布任何服务 UUID。这并不意味着它没有该服务....它只是不做广告。
您可能想要连接到它,然后调用 discoverServices() 以获取它真正拥有的服务列表...
可能是您的设备公布了无效数据。如果是这样,Android 将 return 一个空的服务列表,即使无效数据位于不相关的字段中也是如此。
所以分析广告数据并检查它是否有你要找的UUID。一旦你明白这是怎么回事,你就可以自己解析数据了。
(以下代码是 Java 而不是 Kotlin。但是 Android Studio 应该会自动转换它。)
@Override
public void onScanResult(int callbackType, ScanResult result) {
super.onScanResult(callbackType, result);
ScanRecord scanRecord = result.getScanRecord();
byte[] advertisementData = scanRecord.getBytes();
Log.i(TAG, "advertisement data: " + bytesToHex(advertisementData));
}
private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
public static String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
for (int j = 0; j < bytes.length; j++) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = HEX_ARRAY[v >>> 4];
hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
}
return new String(hexChars);
}