简体   繁体   English

安卓低功耗。 如何通过原始广告数据过滤扫描

[英]Android BLE. How to filter Scan by raw advertising data

I have to build an Android App that reads information on a kind of device that only shows up on scan when it's filtered (general scans won't show it).我必须构建一个 Android 应用程序来读取一种设备上的信息,该设备仅在被过滤时才会在扫描时显示(一般扫描不会显示它)。 The device is beacon-like, so it only advertises data, which have the info I want on the advertise (it's not connectable).该设备类似于信标,因此它只广告数据,其中包含我想要的广告信息(不可连接)。 The filter that the manufacturer gave to me, is a raw data.制造商给我的过滤器是原始数据。 Which is:这是:

0x02010612435542 0x02010612435542

I can't filter it by name, because the device does not advertise it's name.我无法按名称过滤它,因为该设备不会宣传它的名称。 I can't do it by MAC Address either, because the App won't previously know the device's Address (it will be many devices of that kind).我也不能通过MAC Address来做到这一点,因为应用程序之前不会知道设备的地址(它将是许多此类设备)。

The nrfConnect App, does it nicely, as you can see below: nrfConnect 应用程序做得很好,如下所示:

nrfConnect 正确执行过滤

The filter's name on the App is:应用程序上的过滤器名称是:

Filter by raw advertising data按原始广告数据过滤

And, when filtered, that's how a device shows up on the App:而且,当过滤后,这就是设备在应用程序上的显示方式:

通过原始数据过滤后在 nrfConnect 上找到的设备

So, here is the thing.所以,事情就是这样。 I can't filter either by name or MAC Address .我无法按 name 或MAC Address过滤。

The other options in Java (android/ble standard lib) for filtering are: 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();

I've got the UUID provided by the manufacturer.我有制造商提供的 UUID。 It's它是

B54ADC00-67F9-11D9-9669-0800200C9A66 B54ADC00-67F9-11D9-9669-0800200C9A66

But, as the manufacturer stated, the UUID is used to scan for iOS, won't work on Android (tested it, it's true).但是,正如制造商所说,UUID 用于扫描 iOS,不适用于 Android(经过测试,这是真的)。

So, I'am left with 2 options of the scanFilters above.所以,我只剩下上面 scanFilters 的 2 个选项。

I have knowledge like: "The manufacturer data is advertised within the raw advertising data, which can be found via nrfConnect App. And the first two bytes of the manufacturer data, is the manufacturer ID, to use with the setManufacturerData() filter".我有这样的知识:“制造商数据在原始广告数据中进行广告,可以通过 nrfConnect 应用程序找到。制造商数据的前两个字节是制造商 ID,与setManufacturerData()过滤器一起使用”。 I even was able to retrieve the raw manufacturer advertised data (using the setDeviceAddress() filter (for testing, using a test-device, because as I said, the App won't know the MACAddresses previously), and I got something like this:我什至能够检索原始制造商广告数据(使用setDeviceAddress()过滤器(用于测试,使用测试设备,因为正如我所说,应用程序之前不知道 MACAddresses),我得到了这样的东西:

0X020106124355420000080390BECB49400400CB500CF 0X020106124355420000080390BECB49400400CB500CF

Sorry for the long question, but I tried to make it the most complete I could.抱歉问了这么长的问题,但我尽量使它尽可能完整。

I have tried everything I could using those scanFilter methods, but couldn't get it to work.我已经尝试了所有可以使用这些 scanFilter 方法的方法,但无法使其正常工作。

Someone knows how to implement this?有人知道如何实现这个吗? I am going crazy for over a MONTH on this.我为此疯狂了一个多月。

Thanks in advance!提前致谢!

I Finally figured it out with two methods.我终于用两种方法弄清楚了。

  1. Using ScanCallback使用 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) { // } };
  2. Using LeScanCallback使用 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. } };

You can filter out the device you want from this byte array.你可以从这个字节数组中筛选出你想要的设备。

For example:例如:

To find out only Heart Rate Monitor Device, I have converted the scanRecord byte array to a string and then checked the occurrence of "0d 18" in it.为了仅找出心率监测设备,我已将 scanRecord 字节数组转换为字符串,然后检查其中是否出现了“0d 18”。

If the device raw advertising data contains "0d 18" string, it is a Heart rate monitor otherwise it's not.如果设备原始广告数据包含“0d 18”字符串,则它是心率监测器,否则不是。

Let me know if anyone still needs help如果有人还需要帮助,请告诉我

I finally found a solution.我终于找到了解决方案。 It doesn't answer the question about the filter scan by raw advertising data but, I could scan for the devices I needed.它没有回答有关通过原始广告数据进行过滤器扫描的问题,但是,我可以扫描我需要的设备。 This is what I did:这就是我所做的:

First, I made a filter by name.首先,我按名称做了一个过滤器。 Although the device have no name, I filter by name to scan for devices whose name == null .虽然设备没有名称,但我按名称过滤以扫描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;
}

After that, I needed a second filter (which wasn't on the scanFilters()method above, it was on the scanResult) because it was returning me a huge amount of devices, and that filter was by the MAC Address prefix (which is the same for my devices).在那之后,我需要第二个过滤器(它不在上面的 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());
        }
    }
};

And finaly, I got to scan only the devices I needed.最后,我只需要扫描我需要的设备。 I still want to know the main question so, if someone have a solution to this, please feel free to answer.我仍然想知道主要问题,所以如果有人对此有解决方案,请随时回答。 Thanks!谢谢!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM