Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bluetooth LE Scan filter not working

I want to only scan BLE beacons with a specific UUID in my Android code. Even though I can add filter for specific MAC addresses, I cannot make it work with UUIDs. onScanResult function is never called. Why could that be? I'm using API 21 and I'm not getting any errors for the project.

final String tagUUID = "01122334-4556-6778-899a-abbccddeeff0";

//does not work
ScanFilter filter = new ScanFilter.Builder().setServiceUuid(new ParcelUuid(UUID.fromString(tagUUID))).build();

//works
ScanFilter filter = new ScanFilter.Builder().setDeviceAddress(tagMAC).build();
like image 440
Alice Van Der Land Avatar asked Apr 16 '15 02:04

Alice Van Der Land


2 Answers

I'm the author of the blog post mentioned above. Here's how to fix your issue for Android 21+.

// Empty data
byte[] manData = new byte[]{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

// Data Mask
byte[] mask = new byte[]{0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0};

// Copy UUID into data array and remove all "-"
System.arraycopy(hexStringToByteArray("YOUR_UUID_TO_FILTER".replace("-","")), 0, manData, 2, 16);

// Add data array to filters
ScanFilter filter = new ScanFilter.Builder().setManufacturerData(76, manData, mask).build());

public static byte[] hexStringToByteArray(String s) {
    int len = s.length();
    byte[] data = new byte[len / 2];
    for (int i = 0; i < len; i += 2) {
        data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                + Character.digit(s.charAt(i+1), 16));
    }
    return data;
}

The issue here is that you can add UUID filtering but its not exactly straight forward

like image 74
Ted Eriksson Avatar answered Nov 08 '22 21:11

Ted Eriksson


It is possible that the filtering looks for the service UUID in the "Service UUID" AD Type Advertising Structure. Which actually makes sense and that's how it should work.

For beacons, the UUID you are trying to find is actually located in the "Manufacturer Specific Data" AD Type structure. And nobody cares about looking for Service UUIDs there.

I believe that the service UUID filtering is only meant to filter for UUIDs of services in the GATT Database; those UUIDs would be located as I explained in the first paragraph.

That UUID in beacons is not a service UUID per se. It is rather a beacon identifier with an UUID format.

like image 43
Bogdan Alexandru Avatar answered Nov 08 '22 19:11

Bogdan Alexandru