![](/img/trans.png)
[英]Android BLE. Is it possible to use a regex as a filter to scan for Mac Address?
[英]Android BLE. How to filter Scan by raw advertising data
我必须构建一个 Android 应用程序来读取一种设备上的信息,该设备仅在被过滤时才会在扫描时显示(一般扫描不会显示它)。 该设备类似于信标,因此它只广告数据,其中包含我想要的广告信息(不可连接)。 制造商给我的过滤器是原始数据。 这是:
0x02010612435542
我无法按名称过滤它,因为该设备不会宣传它的名称。 我也不能通过MAC Address
来做到这一点,因为应用程序之前不会知道设备的地址(它将是许多此类设备)。
nrfConnect 应用程序做得很好,如下所示:
应用程序上的过滤器名称是:
按原始广告数据过滤
而且,当过滤后,这就是设备在应用程序上的显示方式:
所以,事情就是这样。 我无法按 name 或MAC Address
过滤。
Java(android/ble标准库)中用于过滤的其他选项是:
ScanFilter scanFilter1 = new ScanFilter.Builder().setManufacturerData(manufacturerId, manufacturerData).build();
ScanFilter scanFilter2 = new ScanFilter.Builder().setServiceData(serviceDataUuid, serviceData).build();
ScanFilter scanFilter2 = new ScanFilter.Builder().setServiceUuid(serviceUuid).build();
我有制造商提供的 UUID。 它是
B54ADC00-67F9-11D9-9669-0800200C9A66
但是,正如制造商所说,UUID 用于扫描 iOS,不适用于 Android(经过测试,这是真的)。
所以,我只剩下上面 scanFilters 的 2 个选项。
我有这样的知识:“制造商数据在原始广告数据中进行广告,可以通过 nrfConnect 应用程序找到。制造商数据的前两个字节是制造商 ID,与setManufacturerData()
过滤器一起使用”。 我什至能够检索原始制造商广告数据(使用setDeviceAddress()
过滤器(用于测试,使用测试设备,因为正如我所说,应用程序之前不知道 MACAddresses),我得到了这样的东西:
0X020106124355420000080390BECB49400400CB500CF
抱歉问了这么长的问题,但我尽量使它尽可能完整。
我已经尝试了所有可以使用这些 scanFilter 方法的方法,但无法使其正常工作。
有人知道如何实现这个吗? 我为此疯狂了一个多月。
提前致谢!
我终于用两种方法弄清楚了。
使用 ScanCallback
ScanCallback mScanCallback = new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { byte[] scanRecord = result.getScanRecord().getBytes(); //scanRecord will give you the raw advertisement data given by the device in byte array. } @Override public void onBatchScanResults(List<ScanResult> results) { for (ScanResult sr : results) { // } } @Override public void onScanFailed(int errorCode) { // } };
使用 LeScanCallback
BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() { @Override public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) { //scanRecord will give you the raw advertisement data given by the device in byte array. } };
你可以从这个字节数组中筛选出你想要的设备。
例如:
为了仅找出心率监测设备,我已将 scanRecord 字节数组转换为字符串,然后检查其中是否出现了“0d 18”。
如果设备原始广告数据包含“0d 18”字符串,则它是心率监测器,否则不是。
如果有人还需要帮助,请告诉我
我终于找到了解决方案。 它没有回答有关通过原始广告数据进行过滤器扫描的问题,但是,我可以扫描我需要的设备。 这就是我所做的:
首先,我按名称做了一个过滤器。 虽然设备没有名称,但我按名称过滤以扫描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;
}
在那之后,我需要第二个过滤器(它不在上面的 scanFilters() 方法上,它在 scanResult 上)因为它返回给我大量的设备,并且该过滤器是通过 MAC 地址前缀(这是我的设备也是如此)。
private Set<String> btDevice = 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")) {
btDevice.add(device.getAddress());
}
}
};
最后,我只需要扫描我需要的设备。 我仍然想知道主要问题,所以如果有人对此有解决方案,请随时回答。 谢谢!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.