我有一个自定义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
)
是否有人有更多关于基于serviceUUID的扫描过滤器如何工作的详细信息,并且外围设备必须满足哪些条件才能被过滤器接受?
我想出了使它起作用的方法。问题是我的过滤器是on serviceUuid
,我假设它查看的是在advertisedServices
集合中通告UUID的外围设备。我的外围设备仅在其serviceData
关联数组中公布UUID作为密钥,因此我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
)
}
问题是现在过滤器太宽松了,因为我为周围的每个外围设备(即使没有外围设备)都获得了回调serviceData
,就像我根本没有指定过滤器一样。可能是因为我null
作为第二个参数传递给setServiceData
了过滤器,因为我不知道要在此添加什么。而且文档并没有完全有用。
我的猜测是,扫描足以在后台运行(我还没有尝试过),但是如果我可以限制调用回调的次数并且不必过滤,那将更有意义。我。