当前位置: 首页 > 知识库问答 >
问题:

AndroidBLE。如何通过原始广告数据过滤扫描

鲁鸿朗
2023-03-14

我必须构建一个Android应用程序,用于读取一种设备上的信息,该设备仅在过滤时在扫描时显示(一般扫描不会显示它)。该设备类似于信标,因此它仅通告数据,这些数据在通告上具有我想要的信息(它不可连接)。制造商给我的过滤器是原始数据。即:

0x02010612435542

我不能按名称过滤它,因为设备不会宣传它的名称。我也不能通过MAC地址来完成,因为应用程序以前不会知道设备的地址(这将是许多此类设备)。

nrfConnect应用程序做得很好,如下图所示:

应用程序上的过滤器名称为:

按原始广告数据筛选

过滤后,设备就会显示在应用程序上:

所以,事情是这样的。我无法按名称或MAC地址进行过滤。

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上运行(经过测试,这是真的)。

因此,我只剩下上面的两个扫描过滤器选项。

我有这样的知识:“制造商数据在原始广告数据中进行广告,可以通过nrfConnect应用程序找到这些数据。制造商数据的前两个字节是制造商ID,与< code > setManufacturerData()过滤器一起使用。我甚至能够检索原始的制造商广告数据(使用< code>setDeviceAddress()过滤器(用于测试,使用测试设备,因为正如我所说的,应用程序之前不会知道MACAddresses),并且我得到了类似这样的内容:

0 X 020106124355420000080390 BE CB 49400400 CB 500 CF

很抱歉问了这么长的问题,但我已经尽我所能让它更完整了。

我已经尝试了使用这些scanFilter方法所能做的一切,但都没有成功。

有人知道如何实现这一点吗?我为此疯狂了一个多月。

提前感谢!

共有2个答案

太叔昆
2023-03-14

我终于找到了解决办法。它没有回答关于过滤扫描原始广告数据的问题,但我可以扫描我需要的设备。我是这样做的:

首先,我按名字做了一个过滤器。虽然设备没有名称,但我通过名称过滤来扫描< code>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());
        }
    }
};

最后,我只能扫描我需要的设备。我仍然想知道主要的问题,所以,如果有人有这个问题的解决方案,请随时回答。谢谢!

符国安
2023-03-14

我终于用两种方法想通了。

>

  • 使用扫描回拨

             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.
    
                         }
                     };
    

    您可以从此字节数组中筛选出所需的设备。

    例如:

    为了只找出心率监视器设备,我已将scanList字节数组转换为字符串,然后检查其中“0d 18”的出现情况。

    如果设备原始广告数据包含“0d 18”字符串,则它是心率监视器,否则不是。

    如果还有人需要帮助,请告诉我

  •  类似资料:
    • 我正在Android(移动设备a)上执行UUID过滤扫描,我有两个测试用例。 一个人在另一个Android设备(移动设备b)上使用一个名为BLE扫描仪的应用程序来创建一个具有两个测试服务的BLE服务器(每个服务都有自己唯一的UUID)。另一种是通过Arduino BLE服务器,为其服务定制UUID。 如果我使用移动设备B的BLE扫描仪应用程序并扫描arduino,我可以找到它,连接到它并查看服务以

    • 我试图子集一个熊猫DataFrame在python基于两个逻辑语句 即。 但是第3行的语法无效。 有没有一种方法可以在一行中完成?

    • 问题内容: 我有一个像这样的数组: 现在,我想按某种条件过滤该数组,只保留值等于2的元素,并删除值不等于2的所有元素。 所以我的预期结果数组将是: 注意:我想保留原始数组中的键。 如何使用PHP做到这一点?有内置功能吗? 问题答案:

    • 我是AWS和Dynamo的新手。我正在使用React.js前端和AWS(Gateway API、Lambda、Dynamo)后端进行我的项目。这是我的应用位置: https://www.alphaux.com 单击“获取提示”后,我收到服务器响应。如果我单击一个关键字-这些关键字将添加到请求的GET参数列表中,如:topic=blah 以下是我的问题的详细信息: 在我的Lambda中:…const

    • 问题内容: 如何在Java中通过引用传递基本类型?例如,如何使传递给方法的值可修改? 问题答案: 在Java中,没有一种方法可以通过引用直接传递基元。 一种解决方法是改为将引用传递给包装类的实例,该实例然后将原语包含为成员字段。这样的包装器类可能非常容易为自己编写: 但是,一些预先构建的包装器类又如何,因此我们不必编写自己的包装器类?

    • 本文向大家介绍你认为如何通过大数据优化电梯广告内容?相关面试题,主要包含被问及你认为如何通过大数据优化电梯广告内容?时的应答技巧和注意事项,需要的朋友参考一下 通过大数据获取: 1. 使用电梯的用户画像 包括:年龄、职业、性别、大致收入及消费水平等 2. 电梯的应用场景 是公寓?商场?写字楼?不同的场景下采取不同的广告投放策略 根据不同的用户画像和电梯所处的应用场景,有针对性的投放广告。