蓝牙低功耗扫描过滤器无法正常工作

9

我希望在我的Android代码中只扫描特定UUID的蓝牙信标。尽管我可以添加特定MAC地址的过滤器,但是我无法使用UUID使其正常工作。onScanResult函数从未被调用。这可能是为什么?我正在使用API 21,并且没有收到项目的任何错误。

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();

我找到了一篇小文章,它说明这是4.3的常见问题,但在棒棒糖中已经修复。如果您对此问题有任何更新,请在此处提及,因为我遇到了同样的问题,真的很希望能尽快解决。http://blog.conjure.co.uk/2014/08/ibeacons-and-android-parsing-the-uuid-major-and-minor-values/:) - BigPenguin
2个回答

13

我是上面提到的博客文章的作者。这是如何修复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;
}

问题在于,你可以添加UUID过滤器,但它并不完全直截了当。


byte[] mask 中,1 可以是 (byte)0xFF 吗? 只有最低有效位(LSB)与 1 匹配。 - sumio
1
不,这种情况下它只是告诉扫描过滤器是否关心数据。有关更多详细信息,请参见文档 https://developer.android.com/reference/android/bluetooth/le/ScanFilter.Builder.html#setManufacturerData(int%2C%20byte%5B%5D%2C%20byte%5B%5D)“对于掩码中的任何位,如果需要匹配制造商数据中的一位,则将其设置为1,否则将其设置为0” - Ted Eriksson
我相信@sumio是正确的。在源代码中,掩码应用于所有位,因此每个字节都应该是0xFF。阴险的是,只填充LSB大多数情况下都能工作,因为LSB匹配的概率是2^16中的1。 - Rupert Rawnsley

4
过滤器可能会在“服务UUID”AD类型广告结构中查找服务UUID。这实际上是有道理的,也应该是这样工作的。
对于信标,您要查找的UUID实际上位于“制造商特定数据”AD类型结构中。而且没有人关心在那里寻找服务UUID。
我认为服务UUID过滤仅意味着过滤GATT数据库中服务的UUID;这些UUID将如我在第一段中所解释的那样位于那里。
信标中的UUID本质上并不是服务UUID。它是具有UUID格式的信标标识符。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接