What I want to achieve is, when user enter geofencing, the beacons foreground service will start to run and after one beacon detected, I will kill this foreground service and start to run it on the background just like the sample code on android-beacon-library-reference
library.
private fun monitorBeacons(startForegroundService: Boolean) {
var beaconManager = WolApp.appContext?.beaconManager
if (beaconManager == null) {
WolApp.appContext?.beaconManager = BeaconManager.getInstanceForApplication(WolApp.appContext!!)
beaconManager = WolApp.appContext?.beaconManager
beaconManager?.backgroundMode = true
beaconManager?.beaconParsers?.clear()
beaconManager?.beaconParsers?.add(BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"))
beaconManager?.removeAllMonitorNotifiers()
}
if (startForegroundService) {
setupForegroundNotificationService(WolApp.appContext!!)
} else {
WolApp.appContext?.regionBootstrap?.disable()
WolApp.appContext?.regionBootstrap = null
try {
WolApp.appContext?.beaconManager?.disableForegroundServiceScanning()
} catch (e: IllegalStateException) {}
if (beaconManager?.scheduledScanJobsEnabled == false) {
beaconManager.setEnableScheduledScanJobs(true)
beaconManager.backgroundBetweenScanPeriod = BeaconManager.DEFAULT_BACKGROUND_BETWEEN_SCAN_PERIOD
beaconManager.backgroundScanPeriod = BeaconManager.DEFAULT_BACKGROUND_SCAN_PERIOD
}
}
if (WolApp.appContext?.regionBootstrap == null) {
WolApp.appContext?.regionBootstrap = RegionBootstrap(WolApp.appContext!!, regions)//regions are some iBeacon regions
}
if (!startForegroundService) {
WolApp.appContext?.backgroundPowerSaver = BackgroundPowerSaver(WolApp.appContext!!)
}
}
For setupForegroundNotificationService
method is same with android-beacon-library-reference
library.
I'm not quite sure if I'm doing this right or wrong, can anyone help, please?
It is a little bit tricky to switch a foreground service on or off because you are trying to change the behavior of multiple threads of execution that are already running behind the scenes in existing services.
The key thing missing from the code shown is that you must also make sure you have stopped the library from scanning before you can switch. This is complex because it is asynchronous -- it takes time for the scanner to shut down its threads.
If using regionBootstrap
, the call to regionBootstrap.disable()
does this. (You can also use beaconManager.unbind(...)
if not using regionBootstrap
). But the problem is those APIs do not give you a callback when the scaning service is fully shut down. And restarting it again before it is shut down can cause problems. I do not have a great suggestion here , other than perhaps using a timer -- say one second between stop and start?
You might also want to look at this discussion of a similar setup: https://github.com/AltBeacon/android-beacon-library/issues/845