我正在使用自己的BLE设备。在听完这些设备之后我想使用ScanFilter
,所以我只得到我感兴趣的设备。我现在的解决方案是在回调内部进行过滤,但如果这种过滤可能更早发生并且根据它应该是可能的。我试图过滤制造商的具体数据,但我无法让它工作。这是我的代码:
BluetoothLeScanner bleScanner = bluetoothAdapter.getBluetoothLeScanner();
ScanFilter filter = getScanFilter();
List<ScanFilter> scanFilters = new ArrayList<>();
scanFilters.add(filter);
ScanSettings scanSettings = getScanSettings();
bleScanner.startScan(scanFilters, scanSettings, scanCallback);
这是创建过滤器和设置的功能:
private ScanSetting getScanSettings(){
ScanSettings.Builder builder = new ScanSettings.Builder();
builder.setReportDelay(0);
builder.setScanMode(ScanSettings.SCAN_MODE_LOW_POWER);
return builder.build();
}
private ScanFilter getScanFilter(){
ScanFilter.Builder builder = new ScanFilter.Builder();
ByteBuffer manData = ByteBuffer.allocate(6); //The sensors only sends 6 bytes right now
ByteBuffer manMask = ByteBuffer.allocate(6);
manData.put(0, (byte)0x50);
manData.put(1, (byte)0x41);
manData.put(2, (byte)0x43);
manData.put(3, (byte)0x4b);
manData.put(4, (byte)0x45);
manData.put(5, (byte)0x54);
for(int i = 0; i < 6; i++){
manMask.put((byte)0x01);
}
builder.setManufacturerData(20545, manData.array(), manMask.array()); //Is this id correct?
return builder.build();
}
如果我不使用任何只有此功能的过滤器或设置:
bluetoothLeScanner.startScan(scanCallback);
我得到了我的BLE设备,所以我知道它们正在正确播放。我还可以打印制造商特定的数据,并且可以看到它是我在过滤器中使用的6个相同字节。我不确定id(.setManufacturerData
函数中的第一个参数)是否正确,因为我能找到的唯一信息来自于ScanFilter.Builder:
"Note the first two bytes of the manufacturer Data is the manufacturerId"
当我使用此代码并尝试扫描设备后,我什么都没得到。我在这里缺少什么?
答案 0 :(得分:1)
我设法让它发挥作用。这是不正确的manufacturerId。我从前两个字节得到的不是20545。相反,我发现我可以通过执行以下操作从ScanResult
(当我没有使用过滤器时)获取此ID:
ScanRecord scanRecord = scanResult.getScanRecord();
SparseArray<byte[]> manufacturerData = scanRecord.getManufacturerSpecificData();
for(int i = 0; i < manufacturerData .size(); i++){
int manufacturerId = manufacturerData.keyAt(i);
}
通过这样做,我得到了正确的manufacturerId,然后我可以放在bleScanner.startScan
函数中。
答案 1 :(得分:0)
SIG定义了“制造商特定数据”,以包括制造商ID作为前2个字节,后跟任何其他数据。然后,Android会通过提取前2个字节(剩下的剩余字节)来确定制造商ID。如果您的广告包没有使用制造商ID(不建议使用,但根据我的情况),那么Android的“制造商数据”实际上将丢失您的2个字节。
就我而言,固件工程师需要为数据分配所有字节。因此,我最终在Android端错误地解析了制造商数据。
解决方案是将过滤器的前两个字节分隔为ID的整数。其余字节用于数据。像这样:
fun createAndroidManufacturerDataFilter(query: String): ScanFilter {
return ScanFilter.Builder().setManufacturerData(
convertASCIItoByteArrayToInt(query.substring(0, 2)),
convertASCIItoByteArray(query.substring(2))
).build()
}