使用基于发布的服务UUID的扫描筛选器扫描BLE外设

Seb*_*ien 7 android bluetooth-lowenergy android-ble

我有一个自定义BLE外围设备,它发布这样的数据:

在此处输入图片说明

换句话说,我的BLE外设会在已发布的服务数据中发布与唯一标识符关联的服务UUID,但不会将该服务UUID添加到已发布的服务列表中,因为如果这样做,则BLE框架中没有空间在需要时添加电池电量。

在iOS上,我可以使用基于服务UUID的过滤器进行扫描,并查看我的外围设备。但是在Android上,使用以下扫描过滤器,我看不到外围设备:

val scanSettingsBuilder = ScanSettings.Builder()
            .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
            .setReportDelay(0L)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    scanSettingsBuilder
                .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES)
                .setMatchMode(ScanSettings.MATCH_MODE_AGGRESSIVE)
                .setNumOfMatches(ScanSettings.MATCH_NUM_ONE_ADVERTISEMENT)
}
bluetoothAdapter?.bluetoothLeScanner?.startScan(
    arrayListOf(ScanFilter.Builder().setServiceUuid(ParcelUuid(UUID.fromString("00004865-726f-6e54-7261-636b2d475053"))).build()),
    scanSettingsBuilder.build(),
    leScanCallback
)
Run Code Online (Sandbox Code Playgroud)

是否有人有更多关于基于serviceUUID的扫描过滤器如何工作的详细信息,并且外围设备必须满足哪些条件才能被过滤器接受?

Seb*_*ien 5

我想出了如何让它工作......有点。问题是我的过滤器是 on serviceUuid,我假设它会查看在advertisedServices集合中宣传 UUID 的外围设备。我的外围设备仅将 UUID 作为其serviceData关联数组中的键进行广告,因此我serviceData按如下方式切换到过滤器,现在我可以找到我的外围设备:

AsyncTask.execute {
    val scanFilters = Settings.scannedBleServices.values.map {
        ScanFilter.Builder().setServiceData(it, null).build()
    }
    val scanSettingsBuilder = ScanSettings.Builder()
            .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
            .setReportDelay(0L)
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        scanSettingsBuilder
                .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES)
                .setMatchMode(ScanSettings.MATCH_MODE_AGGRESSIVE)
                .setNumOfMatches(ScanSettings.MATCH_NUM_ONE_ADVERTISEMENT)
    }
    bluetoothAdapter?.bluetoothLeScanner?.startScan(
            scanFilters,
            scanSettingsBuilder.build(),
            leScanCallback
    )
}
Run Code Online (Sandbox Code Playgroud)

问题是现在过滤器太宽松了,因为我得到了周围每个外围设备的回调,即使是那些没有任何外围设备的回调serviceData,就像我根本没有指定过滤器一样。也许是因为我在过滤器中null作为第二个参数传递setServiceData了,因为我不知道还要在那里添加什么。而且文档并不完全有用。

我的猜测是扫描在后台工作就足够了(我还没有尝试过),但是如果我可以限制调用回调的次数并且我不必过滤就更有意义了我。