Scanning for BLE peripherals with a scan filter based on advertised service UUID
I figured out how to make it work... sort of. The problem is that my filter was on serviceUuid
, which I assume looks at peripherals that advertise the UUID in the advertisedServices
collection. My peripheral only advertises the UUID as a key in its serviceData
associative array, so I switched to the serviceData
filter as follows, and now I can find my peripheral:
AsyncTask.execute {
val scanFilters = Settings.scannedBleServices.values.map {
ScanFilter.Builder().setServiceData(it, null).build()
}
val scanSettingsBuilder = ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
.setReportDelay(0L)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
scanSettingsBuilder
.setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES)
.setMatchMode(ScanSettings.MATCH_MODE_AGGRESSIVE)
.setNumOfMatches(ScanSettings.MATCH_NUM_ONE_ADVERTISEMENT)
}
bluetoothAdapter?.bluetoothLeScanner?.startScan(
scanFilters,
scanSettingsBuilder.build(),
leScanCallback
)
}
The problem is that now the filter is too permissive, as I get a callback for every peripheral around, even those without any serviceData
, just as if I had specified no filter at all. Maybe it's because I passed null
as a second parameter to setServiceData
in the filter because I didn't know what else to add there. And the documentation is not exactly helpful.
My guess is that it's enough for the scan to work in the background (I haven't tried yet), but it would make more sense if I could restrict the number of times the callback is called and I didn't have to filter by myself.