30

我正在使用最新的 android 8.1.0 更新的像素。

我面临与 BLE 广告扫描相关的问题。每当我关闭屏幕(即按下电源按钮)我的扫描就会停止。打开屏幕后它将立即重新启动。

我检查了 BLE 的最新代码。google 新引入了这个功能(参考链接)。

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

4

4 回答 4

50

从 Android 8.1 开始,屏幕关闭时会阻止未经过滤的蓝牙扫描。虽然在 Android 的次要版本中做出如此巨大的变化令人惊讶,但这肯定是基于提交中的评论的预期变化: 当屏幕熄灭时停止未经过滤的 BLE 扫描。

解决方法是对所有扫描使用 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();

如果需要,您可以将多个过滤器添加到单个扫描中,任何匹配的都将返回结果。这里唯一真正的限制是您必须知道所有制造商代码或您可能预先匹配的所有 GATT 服务 UUID,至少在关闭屏幕进行扫描时是这样。

您使用如下代码开始扫描:

bluetoothAdapter.getBluetoothLeScanner().startScan(filters, settings, scanCallback);

编辑:也可以使用如下所示的 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 的三星设备上,即使扫描过滤器为空,扫描也会在屏幕关闭的情况下被阻止。如上所述,使用非空扫描过滤器可以在屏幕关闭的情况下进行扫描。

于 2018-01-03T14:53:53.940 回答
2

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

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

于 2019-08-26T08:49:28.260 回答
0

显然不是,除非他们错过了什么。但是,如果您有扫描过滤器,它仍然可以在后台工作,无论如何您都应该拥有它。那么这真的是一个问题吗?

于 2018-01-03T13:51:15.883 回答
0

在 android 11 scanFilter 不能为空,你需要设置一些东西,然后会像这样工作:

List<ScanFilter> filterList = new ArrayList<>();
        filterList.add(new ScanFilter.Builder().setDeviceAddress(address).build());
BluetoothAdapter.getBluetoothLeScanner().startScan(filterList, scanSettings, scanCallback);
于 2021-07-14T02:56:04.377 回答