使用BluetoothLeScanner for android 时如何过滤制造商数据?

Few*_*rds 5 android bluetooth-lowenergy

我正在使用我自己的 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);
Run Code Online (Sandbox Code Playgroud)

这是创建过滤器和设置的函数:

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();
}
Run Code Online (Sandbox Code Playgroud)

如果我不使用任何过滤器或仅具有此功能的设置:

bluetoothLeScanner.startScan(scanCallback);
Run Code Online (Sandbox Code Playgroud)

我得到了我的 BLE 设备,所以我知道它们正在正确广播。我还可以打印制造商特定的数据,并且可以看到它与我在过滤器中使用的 6 个字节相同。我不确定 id(.setManufacturerData函数中的第一个参数)是否正确,因为我能找到的关于此的唯一信息来自 android 开发者页面的以下文本ScanFilter.Builder:

"Note the first two bytes of the manufacturer Data is the manufacturerId"
Run Code Online (Sandbox Code Playgroud)

当我使用此代码并尝试在设备后扫描时,我什么也没得到。我在这里缺少什么?

Few*_*rds 5

我设法让它工作。是制造商 ID 不正确。我从前两个字节得到的不是 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);
}
Run Code Online (Sandbox Code Playgroud)

通过这样做,我得到了正确的制造商 ID,然后我可以将其放入bleScanner.startScan函数中。

  • “manufacturerId”(又名公司标识符)标识 BLE 设备的制造商,并由蓝牙 SIG 唯一分配。因此,如果您正在开发 BLE 设备,您必须拥有自己的 ID(除非您同意使用他人的 ID)。在分配公司 ID 之前,id 0xFFFF 可用于内部测试。更多信息:https://www.bluetooth.com/specifications/assigned-numbers/company-identifiers (3认同)