在 Android 上进行持续且响应迅速的信标检测
Continuous and responsive Beacons detection on Android
在我们的项目中,我们需要非常快速(最好在几秒内)、可靠且连续的信标检测,最重要的是在后台进行。现在我们正在使用 AltBeacon 库,BeaconManager 是在前台服务的上下文中启动的(提供的代码)。
在前台它几乎可以在任何设备上完美运行,问题在于在后台工作。一些后台设备在一段时间后不工作(例如,华为 P9 2017,我知道这是设备的问题)。一般来说,我们需要更好的可靠性。
最大的问题是后台对 Oreo 的检测很慢——从几秒到很长几分钟,直到它报告第一个信标。我已经阅读了 AltBeacon 网站上有关 Oreo 更改的条目,所以我知道系统存在限制。
所以这是我的问题,有什么方法可以提高检测响应能力(最好是在所有 android 版本上)?即使以更大的电池消耗或一些黑客攻击为代价?我试过至少从系统中的电池优化中得到一个例外,但结果可能是一样的。
后台服务中的 BeaconManager 配置:
@Override
public void onCreate() {
super.onCreate();
beaconManager = BeaconManager.getInstanceForApplication(this);
beaconManager.setForegroundScanPeriod(1500);
beaconManager.setForegroundBetweenScanPeriod(0);
beaconManager.setBackgroundScanPeriod(1500);
beaconManager.setBackgroundBetweenScanPeriod(0);
beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout(BeaconParser.EDDYSTONE_UID_LAYOUT));
beaconManager.bind(this);
if (CommConstants.sdkIsAtLeastSDK(21)) {
BluetoothMedic medic = BluetoothMedic.getInstance();
medic.enablePowerCycleOnFailures(this);
medic.enablePeriodicTests(this, BluetoothMedic.SCAN_TEST);
}
goForeground();
}
开始监控:
private static final Region REGION = new Region(BuildConfig.APPLICATION_ID, null, null, null);
protected void startBeaconMonitoring() {
if (beaconManager.isBound(this)) {
findingEnabled = true;
beaconManager.addRangeNotifier(
(collection, region) -> {
for (Beacon beacon : collection) {
// beacon processing
}
});
try {
mLogger.debug("Started beacon monitoring");
beaconManager.startRangingBeaconsInRegion(REGION);
beaconManager.startMonitoringBeaconsInRegion(REGION);
} catch (RemoteException e) {
LoggerFactory.getLogger(App.class).error("Monitoring start exception", e);
}
regionBootstrap = new RegionBootstrap(this, REGION);
startLocationUpdates();
}
}
我注意到 android-beacon-library 中有一个关于信标服务位于前台的 PR,这是否会提高可靠性?
问题
默认情况下,运行ning Android 8+ 上的库将使用 JobScheduler 在您的应用程序处于后台时安排扫描。但是因为Android限制JobScheduler中的作业每15分钟一次,所以调用beaconManager.setBackgroundBetweenScanPeriod(0);
对Android没有影响8.最新的库版本在LogCat中引入了关于这个的警告:Setting a short backgroundBetweenScanPeriod has no effect on Android 8+, which is limited to scanning every ~15 minutes
。有关此限制的更多详细信息,请参见此处:
http://www.davidgyoungtech.com/2017/08/07/beacon-detection-with-android-8
已知解
Android 8 上的前台服务会让服务 运行 持续扫描信标,就像 Android 4.x-7.x 一样。众所周知,将图书馆的扫描服务设为前台服务是可行的。这由库版本 2.15+ 原生支持。有关详细信息,请参阅 here。
可能的选择
如果您拥有独立于图书馆扫描服务的自定义前台服务,则可以使用它来保持您的应用 运行宁。但是你必须关闭 JobSceduler 扫描:
beaconManager.setSceduledScanJobsEnabled(false);
因为以上在 Android 8+ 上默认为 true。进行该更改后,将使用长期 运行ning 服务以您指定的速率安排扫描。
这行得通吗?目前还不清楚,因为图书馆的扫描服务仍然不是前台服务,并且可能在后台 运行ning > 5 分钟后被 Android 8 杀死。您的应用程序中有另一项服务是前台服务这一事实可能足以或可能不足以 Android 8 让扫描服务生效。你将不得不尝试。
在我们的项目中,我们需要非常快速(最好在几秒内)、可靠且连续的信标检测,最重要的是在后台进行。现在我们正在使用 AltBeacon 库,BeaconManager 是在前台服务的上下文中启动的(提供的代码)。
在前台它几乎可以在任何设备上完美运行,问题在于在后台工作。一些后台设备在一段时间后不工作(例如,华为 P9 2017,我知道这是设备的问题)。一般来说,我们需要更好的可靠性。
最大的问题是后台对 Oreo 的检测很慢——从几秒到很长几分钟,直到它报告第一个信标。我已经阅读了 AltBeacon 网站上有关 Oreo 更改的条目,所以我知道系统存在限制。 所以这是我的问题,有什么方法可以提高检测响应能力(最好是在所有 android 版本上)?即使以更大的电池消耗或一些黑客攻击为代价?我试过至少从系统中的电池优化中得到一个例外,但结果可能是一样的。
后台服务中的 BeaconManager 配置:
@Override
public void onCreate() {
super.onCreate();
beaconManager = BeaconManager.getInstanceForApplication(this);
beaconManager.setForegroundScanPeriod(1500);
beaconManager.setForegroundBetweenScanPeriod(0);
beaconManager.setBackgroundScanPeriod(1500);
beaconManager.setBackgroundBetweenScanPeriod(0);
beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout(BeaconParser.EDDYSTONE_UID_LAYOUT));
beaconManager.bind(this);
if (CommConstants.sdkIsAtLeastSDK(21)) {
BluetoothMedic medic = BluetoothMedic.getInstance();
medic.enablePowerCycleOnFailures(this);
medic.enablePeriodicTests(this, BluetoothMedic.SCAN_TEST);
}
goForeground();
}
开始监控:
private static final Region REGION = new Region(BuildConfig.APPLICATION_ID, null, null, null);
protected void startBeaconMonitoring() {
if (beaconManager.isBound(this)) {
findingEnabled = true;
beaconManager.addRangeNotifier(
(collection, region) -> {
for (Beacon beacon : collection) {
// beacon processing
}
});
try {
mLogger.debug("Started beacon monitoring");
beaconManager.startRangingBeaconsInRegion(REGION);
beaconManager.startMonitoringBeaconsInRegion(REGION);
} catch (RemoteException e) {
LoggerFactory.getLogger(App.class).error("Monitoring start exception", e);
}
regionBootstrap = new RegionBootstrap(this, REGION);
startLocationUpdates();
}
}
我注意到 android-beacon-library 中有一个关于信标服务位于前台的 PR,这是否会提高可靠性?
问题
默认情况下,运行ning Android 8+ 上的库将使用 JobScheduler 在您的应用程序处于后台时安排扫描。但是因为Android限制JobScheduler中的作业每15分钟一次,所以调用beaconManager.setBackgroundBetweenScanPeriod(0);
对Android没有影响8.最新的库版本在LogCat中引入了关于这个的警告:Setting a short backgroundBetweenScanPeriod has no effect on Android 8+, which is limited to scanning every ~15 minutes
。有关此限制的更多详细信息,请参见此处:
http://www.davidgyoungtech.com/2017/08/07/beacon-detection-with-android-8
已知解
Android 8 上的前台服务会让服务 运行 持续扫描信标,就像 Android 4.x-7.x 一样。众所周知,将图书馆的扫描服务设为前台服务是可行的。这由库版本 2.15+ 原生支持。有关详细信息,请参阅 here。
可能的选择
如果您拥有独立于图书馆扫描服务的自定义前台服务,则可以使用它来保持您的应用 运行宁。但是你必须关闭 JobSceduler 扫描:
beaconManager.setSceduledScanJobsEnabled(false);
因为以上在 Android 8+ 上默认为 true。进行该更改后,将使用长期 运行ning 服务以您指定的速率安排扫描。
这行得通吗?目前还不清楚,因为图书馆的扫描服务仍然不是前台服务,并且可能在后台 运行ning > 5 分钟后被 Android 8 杀死。您的应用程序中有另一项服务是前台服务这一事实可能足以或可能不足以 Android 8 让扫描服务生效。你将不得不尝试。