Reputation: 519
I am developing an Application that has a BLE device that only shows up on scan when some parameters are sent on scanning.
The App nrf Connect do this task very well (When filter by raw data, and use the 0x02010612435542
raw data parameter).
The device won't show its name, neither it's UUID's, nor manufacturer data.
On nrf Connect, the only thing it shares is a raw return like this: 0X020106124355420000080390BECB49400400CB500CF
(which is preciselly what I need right now).
And on scan by Mac Address (testing on one unit of the device), it only gets me its rssi)
My question is, just like nrfConnect, how can I code a filter or something like that, that will be sent as a parameter on scanning, so I can find my devices? The devices doesn't have names (it shows N/A on scan), and I can't add a list of Mac Address filters because there will be tons of devices of the same kind, when my application is finished.
private List<ScanFilter> scanFilters() {
List<ScanFilter> list = new ArrayList<ScanFilter>();
ScanFilter scanFilter = new ScanFilter.Builder().build();
list.add(scanFilter);
//What kind of filter do I use to send that data on scanning?
return list;
}
Upvotes: 1
Views: 1274
Reputation: 519
I finally found the solution to my problem.
It wasn't the way I was thinking, but thanks to @matdev, I managed to figure it out somehow. And it does not answer the main question, i.e. if it is possible to send data to devices on scan, but, the solution works for me.
First, I made a filter by name, in which the device name == null
.
private List<ScanFilter> scanFilters() {
List<ScanFilter> list = new ArrayList<ScanFilter>();
ScanFilter scanFilterName = new ScanFilter.Builder().setDeviceName(null).build();
list.add(scanFilterName);
return list;
}
It gave me a huge list with tons of devices. So I added another filter, but this time, on the scanResult()
. This other filter is by MAC Address
suffix, as pointed by @matdev, it is the same for my devices.
private Set<String> btDeviceData = new LinkedHashSet<String>();
private ScanCallback scanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
BluetoothDevice device = result.getDevice();
ScanRecord record = result.getScanRecord();
byte[] dataByteArray = record.getBytes();
if (device.getAddress().startsWith("F8:36:9B")) {
btDeviceData.add(device.getAddress());
}
}
};
By doing this, I got a list (Set
to be specific) with only the devices I was looking for.
Upvotes: 1
Reputation: 4283
In your BLE scanner, you receive ScanResult
containing an instance of BluetoothDevice
i.e. the device scanned. At the very least, you should be able to read the BLE address of the device i.e. its hardware address. Use the method:
BluetoothDevice.getAddress();
This hardware address should have a predefined range, such as starting with "A3:B4" which enables filtering scanRecords. Ask your device manufacturer for how these hardware addresses are generated.
Also, if you know the manufacturer id of the devices you are supporting, you can set a filter based on manufacturer data:
ScanFilter scanFilter = new ScanFilter.Builder()
.setManufacturerData(manufacturerId, manufacturerData)
.build();
Note the first two bytes of the manufacturerData array is the manufacturerId.
EDIT: The manufacturerData are part of the bytes array returned by
scanResult.getScanRecord().getBytes()
The scanResult
is passed to the ScanCallback
you've given to BluetoothLESCanner.startScan(...)
Upvotes: 1