我正在使用带有最新Android 8.1.0更新的像素。
我正面临与BLE广告扫描相关的问题。每当我关闭屏幕(即按下电源按钮)时,我的扫描将停止。 它会在打开屏幕后立即重启。
我检查了BLE的最新代码。谷歌新推出此功能(Reference Link)。
有没有办法跳过这部分,我的意思是无论屏幕打开还是关闭,扫描都不应该停止。
答案 0 :(得分:32)
从Android 8.1开始,屏幕关闭时会阻止未过滤的蓝牙扫描。虽然在Android的次要版本中进行如此戏剧性的更改是令人惊讶的,但这肯定是基于提交中的注释的预期更改: Stop unfiltered BLE scans when the screen goes off.
解决方法是对所有扫描使用ScanFilter。新的8.1操作系统代码只是验证屏幕关闭时激活的任何扫描都至少有一个扫描过滤器。如果满足这些条件,扫描结果将按照Android 8.0.x及更早版本的方式提供。
要设置此类扫描,您必须使用Android 5.0中引入的API,并在每次扫描时创建ScanFilter
。以下是一个过滤器,可以找到Apple生产商ID为0x004c的任何设备的制造商广告(这将包括iBeacons):
ScanFilter.Builder builder = new ScanFilter.Builder();
builder.setManufacturerData(0x004c, new byte[] {});
ScanFilter filter = builder.build();
同样,如果您对GATT服务广告感兴趣(例如与Eddystone信标一起使用的那种广告),您可以使用以下过滤器搜索GATT服务UUID:
ScanFilter.Builder builder = new ScanFilter.Builder();
String serviceUuidString = "0000feaa-0000-1000-8000-00805f9b34fb";
String serviceUuidMaskString = "FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF";
ParcelUuid parcelUuid = ParcelUuid.fromString(serviceUuidString);
ParcelUuid parcelUuidMask = ParcelUuid.fromString(serviceUuidMaskString);
builder.setServiceUuid(parcelUuid, parcelUuidMask);
ScanFilter filter = builder.build();
如果需要,您可以为单次扫描添加多个过滤器,任何匹配都将返回结果。这里唯一真正的限制是您必须知道所有制造商代码或您可能预先匹配的所有GATT服务UUID,至少在屏幕关闭时扫描。
您可以使用以下代码开始扫描:
bluetoothAdapter.getBluetoothLeScanner().startScan(filters, settings, scanCallback);
编辑也可以使用 empty ScanFilter
执行此操作,如下所示:
ScanFilter.Builder builder = new ScanFilter.Builder();
ScanFilter filter = builder.build();
如果你使用这样的扫描过滤器,它将匹配任何广告数据包,并且仍允许在Android 8.1上关闭屏幕进行检测,有效地在Android 8.0.x及更早版本中提供相同的行为。
编辑2 :在使用Android 8.1的Galaxy Note 9以及其他带有8.1的三星设备上,即使扫描过滤器空,屏幕也会关闭扫描。如上所述,屏幕关闭时可以使用非空扫描过滤器进行扫描。
答案 1 :(得分:2)
我遇到了同样的问题。即使屏幕被锁定,我也具有扫描过滤器以扫描BLE设备。但是,在三星设备上,它无法正常工作,因此我在三星论坛上搜索,发现了Knox SDK(https://seap.samsung.com/sdk/knox-android)。
这是我的问题的解决方案。您要做的就是将其添加到您的应用中,创建一个许可证并激活它,最后在锁定三星设备屏幕时使用此方法addPackageToBatteryOptimizationWhiteList
来解锁扫描。
答案 2 :(得分:1)
显然不是,除非他们错过了什么。但是如果你有扫描过滤器,它仍然可以在后台工作,无论如何你应该有。这真的是一个问题吗?
答案 3 :(得分:0)
在安卓 11 中 scanFilter 不能为空 你需要设置一些东西然后才能工作 喜欢:
List<ScanFilter> filterList = new ArrayList<>();
filterList.add(new ScanFilter.Builder().setDeviceAddress(address).build());
BluetoothAdapter.getBluetoothLeScanner().startScan(filterList, scanSettings, scanCallback);