BluetoothLeScanner ScanFilter on Service UUID does not work

Viewed 332

I am working on a simple app to scan for BLE devices, and filter the scan results down to find only my ESP32. I want to find my ESP32 by filtering on service UUIDs. I have confirmed that my custom service exists in the advertising data (via nRF Connect listing the service in "Complete list of 128-bit Service UUIDs"). However, when I add the service UUID filter as a ScanFilter before scanning, my ScanCallback is never called. I can however remove the scan filter, and manually check if the service exists in the ScanCallback just fine. See the below code examples.

This first example is using manual filtering, and works just fine.

    private ParcelUuid mServiceUuidFilter = ParcelUuid.fromString("6E400001-B5A3-F393-E0A9-E50E24DCCA9E");

    private final ScanCallback mScanCallback = new ScanCallback() {
        @Override
        public void onScanResult(int callbackType, ScanResult result) {
            boolean matched = (mServiceUuidFilter == null);
            if (mServiceUuidFilter != null && result.getScanRecord().getServiceUuids() != null) {
                for (ParcelUuid uuid : result.getScanRecord().getServiceUuids()) {
                    if (uuid.equals(mServiceUuidFilter)) {
                        matched = true;
                        break;
                    }
                }
            }

            if (matched) {
                // do something
            }
        }
    };
    
private void scan() {
        List<ScanFilter> scanFilters = new ArrayList<>();
        // works
        ScanFilter filter = new ScanFilter.Builder().build();
        scanFilters.add(filter);
        ScanSettings scanSettings = new ScanSettings.Builder().build();

        // skipping mScanner initialization
        mScanner.startScan(scanFilters, scanSettings, mScanCallback);
}

This second example uses a ScanFilter for filtering, and does not work. mScanCallback is never called.

    private ParcelUuid mServiceUuidFilter = ParcelUuid.fromString("6E400001-B5A3-F393-E0A9-E50E24DCCA9E");

    private final ScanCallback mScanCallback = new ScanCallback() {
        @Override
        public void onScanResult(int callbackType, ScanResult result) {
            // do something
        }
    };
    
private void scan() {
        List<ScanFilter> scanFilters = new ArrayList<>();
        // does not work
        ScanFilter filter = new ScanFilter.Builder().setServiceUuid(mServiceUuidFilter).build();
        scanFilters.add(filter);
        ScanSettings scanSettings = new ScanSettings.Builder().build();

        // skipping mScanner initialization
        mScanner.startScan(scanFilters, scanSettings, mScanCallback);
}

Is there something I'm missing here?

1 Answers

Hm, I'm not exactly sure what I changed, but in setting my minimum API level to 21, this started working.

Related