我相信,自从牛轧糖以来,我的应用程序的BLE扫描性能似乎已逐渐降低。我现在可以返回并在棉花糖上进行测试,可以确定那里不存在问题,但是我在Nougat上没有设备了。我在Pie上的Pixel 3a严重显示了问题。
问题
当我的应用程序进行BLE扫描并且我要查找的设备就在我面前时,LE扫描通常需要30-60秒,有时甚至更长的时间,才能将LE扫描返回到ScanCallback中的该设备。我的扫描代码非常简单:
private synchronized void startScan(@Nonnull BluetoothAdapter adapter, UUID[] serviceUuids) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
if (serviceUuids != null && serviceUuids.length > 0) {
adapter.startLeScan(serviceUuids, BleScannerService.this);
} else {
adapter.startLeScan(BleScannerService.this);
}
broadcastUpdate(ACTION_SCAN_STARTED);
} else {
List<ScanFilter> filters = new ArrayList<>();
if (serviceUuids != null && serviceUuids.length > 0) {
for (UUID uuid : serviceUuids) {
filters.add(new ScanFilter.Builder().setServiceUuid(new ParcelUuid(uuid))
.build());
}
}
BluetoothLeScanner scanner = adapter.getBluetoothLeScanner();
if (scanner != null) {
ScanSettings.Builder builder = new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
.setReportDelay(0);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
builder.setMatchMode(ScanSettings.MATCH_MODE_AGGRESSIVE);
}
adapter.getBluetoothLeScanner().startScan(filters,
builder.build(),
mScanCallback);
broadcastUpdate(ACTION_SCAN_STARTED);
} else {
mScanning = false;
}
}
}
该代码中有很大一部分指定了已经为默认值的ScanSettings,但是我已经尽力了。因此,我花了几天的时间进行调试,终于在logcat中找到了一个非常有趣的模式。
每次在ScanCallback中找到设备时,我都会发出一条日志。当我的扫描第一次开始时,它只会每隔一两秒钟就得到一个结果。我什至看到两次扫描结果之间要花费10秒的时间。正是在这段时间里找不到我的BLE设备,大概是因为手机正在使用的巨大扫描间隔都无法与BLE设备的广播间隔保持一致。
但是,在某个时候它刚刚打开,我开始每秒收到很多结果,并且立即找到了我的BLE设备。我最终在闸门打开时每次都找到这些日志(在Pie上):
2019-08-16 09:13:17.813 27109-27109/<my package> E/<my app>: BleScannerService.java:275 onLeScan(): WPW: scanned 88:6B:0F:64:2F:D7
2019-08-16 09:13:28.087 27109-27109/<my package> E/<my app>: BleScannerService.java:275 onLeScan(): WPW: scanned 88:6B:0F:64:2F:D7
2019-08-16 09:13:30.582 27109-27109/<my package> E/<my app>: BleScannerService.java:275 onLeScan(): WPW: scanned 6F:23:65:B7:D9:43
2019-08-16 09:13:33.024 27109-27109/<my package> E/<my app>: BleScannerService.java:275 onLeScan(): WPW: scanned 00:07:80:CF:17:B9
2019-08-16 09:13:33.357 23338-23338/? D/BluetoothGatt: close()
2019-08-16 09:13:33.357 23338-23338/? D/BluetoothGatt: unregisterApp() - mClientIf=7
2019-08-16 09:13:33.363 23338-23338/? D/BluetoothManager: getConnectionState()
2019-08-16 09:13:33.363 23338-23338/? D/BluetoothManager: getConnectedDevices
2019-08-16 09:13:33.407 27109-27109/<my package> E/<my app>: BleScannerService.java:275 onLeScan(): WPW: scanned 6F:90:AC:1D:EF:38
2019-08-16 09:13:33.491 27109-27109/<my package> E/<my app>: BleScannerService.java:275 onLeScan(): WPW: scanned 6F:23:65:B7:D9:43
2019-08-16 09:13:33.524 27109-27109/<my package> E/<my app>: BleScannerService.java:275 onLeScan(): WPW: scanned F4:5C:89:90:C6:24
2019-08-16 09:13:33.625 27109-27109/<my package> E/<my app>: BleScannerService.java:275 onLeScan(): WPW: scanned 46:54:BD:32:A2:EF
2019-08-16 09:13:33.708 27109-27109/<my package> E/<my app>: BleScannerService.java:275 onLeScan(): WPW: scanned F4:5C:89:90:C6:24
2019-08-16 09:13:34.374 23338-23338/? D/BluetoothGatt: connect() - device: C5:8B:66:21:90:5B, auto: true
2019-08-16 09:13:34.374 23338-23338/? D/BluetoothGatt: registerApp()
2019-08-16 09:13:34.374 23338-23338/? D/BluetoothGatt: registerApp() - UUID=35e43611-6c73-47a6-ad0d-9919df01108f
2019-08-16 09:13:34.378 23338-23480/? D/BluetoothGatt: onClientRegistered() - status=0 clientIf=7
2019-08-16 09:13:34.408 27109-27109/<my package> E/<my app>: BleScannerService.java:275 onLeScan(): WPW: scanned 6F:23:65:B7:D9:43
2019-08-16 09:13:34.424 27109-27109/<my package> E/<my app>: BleScannerService.java:275 onLeScan(): WPW: scanned F4:5C:89:90:C6:24
2019-08-16 09:13:34.492 27109-27109/<my package> E/<my app>: BleScannerService.java:275 onLeScan(): WPW: scanned 6F:90:AC:1D:EF:38
2019-08-16 09:13:34.592 27109-27109/<my package> E/<my app>: BleScannerService.java:275 onLeScan(): WPW: scanned 6F:23:65:B7:D9:43
2019-08-16 09:13:34.608 27109-27109/<my package> E/<my app>: BleScannerService.java:275 onLeScan(): WPW: scanned F4:5C:89:90:C6:24
2019-08-16 09:13:34.658 27109-27109/<my package> E/<my app>: BleScannerService.java:275 onLeScan(): WPW: scanned 46:54:BD:32:A2:EF
因此,close()完成的瞬间是水闸打开时。还有一些其他应用程序正在尝试连接到某物,而这种情况下,我的应用程序扫描非常慢(也许Android会自动将其转换为SCAN_MODE_OPPORTUNISTIC或SCAN_MODE_LOW_POWER而不考虑我的SCAN_MODE_LOW_LATENCY?)。
始终存在的另一个日志是“ connect()-设备:C5:8B:66:21:90:5B,自动:true”。我很幸运,能够在手机的蓝牙设置中找到C5:8B:66:21:90:5B ...这是我的Garmin GPS手表!
原因
看来,当我的手表处于蓝牙关闭状态或超出范围时,Garmin Connect应用程序会不断对其进行扫描(嗯,尝试使用自动标记进行连接),这就是导致我的BLE扫描返回结果的原因非常缓慢地。一旦连接超时,我的BLE扫描就会发出尖叫声……Garmin Connect在我的BLE扫描期间进行了另一个连接,但是我想现在我的扫描具有优先权,并且保持快速状态,直到我取消它并重新开始。然后,直到Garmin的连接再次超时为止,它很慢。
我通过几种方式确认了这个问题:
回到棉花糖上的电话,即使安装了Garmin Connect,但手表未连接,也根本不会发生上述问题。我的假设是,Android中发生了一些变化,使得一个应用程序的connect()干扰了另一个应用程序的startScan()。在棉花糖中,它们彼此不干涉,在派中,它们相互干涉。我猜它是基于我读过的许多其他东西开始于牛轧糖,但我无法证实这一点。
有解决方案吗?
我不知道,但是我希望有人在那里。据我所知,实际上没有办法让您的应用“接管”蓝牙适配器,或试图强迫自己比其他使用它的其他应用具有资历(可理解)。
是否有一种方法可以进行BLE扫描,从而不管手机上发生了什么,它都立即变为低延迟状态?它肯定可以在棉花糖中使用...