Issue
I am working with my own BLE-devices. When listening after these devices I would like to use ScanFilter
, so I only get the devices I am interested in. My solution right now is to filter inside the callback but it would be better if this filtration could happen earlier and according to the specification it should be possible. I am trying to filter on the manufacturer specific data but I can not get it to work. This is my code:
BluetoothLeScanner bleScanner = bluetoothAdapter.getBluetoothLeScanner();
ScanFilter filter = getScanFilter();
List<ScanFilter> scanFilters = new ArrayList<>();
scanFilters.add(filter);
ScanSettings scanSettings = getScanSettings();
bleScanner.startScan(scanFilters, scanSettings, scanCallback);
This is the functions that creates the filter and settings:
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();
}
If I don't use any filters or settings with only this function:
bluetoothLeScanner.startScan(scanCallback);
I get my BLE-devices, so I know they are broadcasting correctly. I can also print the manufacturer specific data and can see that it is the 6 same bytes that I use in my filter. I am unsure if the id (the first parameter in the .setManufacturerData
function) is correct because the only info about this I could find was from the following text from the android developer page for the ScanFilter.Builder:
"Note the first two bytes of the manufacturer Data is the manufacturerId"
When I use this code and try to scan after the devices I get nothing. What am i missing here?
Solution
I manage to get it to work. It was the manufacturerId that was not correct. It was not 20545 which I got from the first two bytes. Instead I found out that I could get this id from the ScanResult
(when I used no filter) by doing the following:
ScanRecord scanRecord = scanResult.getScanRecord();
SparseArray<byte[]> manufacturerData = scanRecord.getManufacturerSpecificData();
for(int i = 0; i < manufacturerData .size(); i++){
int manufacturerId = manufacturerData.keyAt(i);
}
By doing this I got the correct manufacturerId that I then could place in the bleScanner.startScan
function.
Answered By - FewWords
Answer Checked By - Mary Flores (JavaFixing Volunteer)