Android 8.1.0 屏幕关闭时 BLE 扫描不工作

BLE scan is not working when screen is off on Android 8.1.0

我正在使用具有最新 android 8.1.0 更新的 Pixel。

我遇到了与 BLE 广告扫描相关的问题。每当我关闭屏幕(即按下电源按钮)时,我的扫描就会停止。 点亮后会立即重启

我已经检查了 BLE 的最新代码。 google新引入此功能(Reference Link)。

有没有办法跳过这部分,我的意思是无论屏幕打开或关闭,扫描都不应该停止。

显然不是,除非他们错过了什么。但如果你有扫描过滤器,它仍然会在后台运行,无论如何你都应该有。所以这真的是个问题吗?

从 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。下面是一个过滤器,可以找到制造商 ID 为 0x004c 的任何 Apple 设备的制造商广告(这将包括 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();

如果需要,您可以将多个过滤器添加到一次扫描中,任何匹配的过滤器都会 return 结果。这里唯一真正的限制是您必须知道所有制造商代码或您可能预先匹配的所有 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 的其他三星设备上,即使扫描为空,扫描也会在屏幕关闭时被阻止筛选。如上所述,在使用非空扫描过滤器关闭屏幕的情况下允许扫描。

我遇到了同样的问题。我有扫描过滤器,以便即使屏幕被锁定也能扫描 BLE 设备。但是在三星设备上它不起作用,所以我在三星论坛上搜索并发现了 Knox SDK (https://seap.samsung.com/sdk/knox-android)。

这就是我的问题的解决方案。您所要做的就是将其添加到您的应用程序,创建许可证并激活它,最后使用此方法addPackageToBatteryOptimizationWhiteList 在三星设备屏幕锁定时解锁扫描。

在 android 11 scanFilter 不能为空 你需要设置一些东西然后才能工作 喜欢:

List<ScanFilter> filterList = new ArrayList<>();
        filterList.add(new ScanFilter.Builder().setDeviceAddress(address).build());
BluetoothAdapter.getBluetoothLeScanner().startScan(filterList, scanSettings, scanCallback);