The library uses a BackgroundPowerSaver class to track the activity lifecycle to determine if the app is in the foreground or background and apply configured scan periods depending on the background mode. As of version 2.19, direct use of this class is deprecated and instead one is automatically created whenever startMonitoring or startRangingBeacons is first called.
The problem with the above is that we don't know the actual foreground/background state of the app when the user makes these calls. Android provides no APIs to determine the current foreground/background status of the app. The preferred approach to doing this is to start tracking activities with the Application.onCreate() method. But this library cannot guarantee that the first call to start monitoring or ranging (which start the internal BackgroundPowerSaver) are made from Application.onCreate(). They often will not be. So the initial background/foreground mode of the library is often wrong.
Here is how it works as of 2.19:
After the first call to startMonitoring/startRangingBeacons, the library will be in the default foreground mode regardless of the actual app foregrounds state
The above will incorrectly use foreground scan periods when the app is launched in the background
The Solution
While we cannot exactly determine the foreground/background state on the first call to startMonitoring/startRangingBeacons, we can infer if it is in the background from a few things:
If the first call to startRangingBecons/startMonitoring has a call stack that includes Application#onCreate, then the library will start out in background mode. This guarantees proper initial mode if you start monitoring there, and this was the documented place to use RegionBootstrap and BackgroundPowerSaver which are the ancestors to the autobind methods.
If the screen is off when during the first call to startRangingBecons/startMonitoring, the library will start out in background mode.
If the screen goes off between the first call to startRangingBecons/startMonitoring and the first time an app activity appears/disappears, the library will switch to background mode.
Impact
Based on the above, the library will always start out in the proper mode if ranging/montioring is first started from:
Application#onCreate (background) which is recommended for background scanning
A visible Activity or Fragment (foreground)
The only times that it may be set wrong will be when it is started from a backgrounded component outside the Application#onCreate call stack. This will often happen I the library starts looking for beacons based on some background event (e.g. a timer, or a signal from a server.). Further, this will only be wrong is if the screen is on at the same time as this happens (e.g. the user is using a different app, has the lock screen or springboard up.)
In the case where the library starts out (incorrectly) in foreground mode, the library will automatically switch to background mode as soon as the screen goes off. As a result, the amount of time in the wrong mode will usually be limited and not have significant battery impact.
The Problem
The library uses a
BackgroundPowerSaver
class to track the activity lifecycle to determine if the app is in the foreground or background and apply configured scan periods depending on the background mode. As of version 2.19, direct use of this class is deprecated and instead one is automatically created wheneverstartMonitoring
orstartRangingBeacons
is first called.The problem with the above is that we don't know the actual foreground/background state of the app when the user makes these calls. Android provides no APIs to determine the current foreground/background status of the app. The preferred approach to doing this is to start tracking activities with the
Application.onCreate()
method. But this library cannot guarantee that the first call to start monitoring or ranging (which start the internalBackgroundPowerSaver
) are made fromApplication.onCreate()
. They often will not be. So the initial background/foreground mode of the library is often wrong.Here is how it works as of 2.19:
The Solution
While we cannot exactly determine the foreground/background state on the first call to startMonitoring/startRangingBeacons, we can infer if it is in the background from a few things:
Application#onCreate
, then the library will start out in background mode. This guarantees proper initial mode if you start monitoring there, and this was the documented place to useRegionBootstrap
andBackgroundPowerSaver
which are the ancestors to the autobind methods.Impact
Based on the above, the library will always start out in the proper mode if ranging/montioring is first started from:
Application#onCreate
(background) which is recommended for background scanningThe only times that it may be set wrong will be when it is started from a backgrounded component outside the
Application#onCreate
call stack. This will often happen I the library starts looking for beacons based on some background event (e.g. a timer, or a signal from a server.). Further, this will only be wrong is if the screen is on at the same time as this happens (e.g. the user is using a different app, has the lock screen or springboard up.)In the case where the library starts out (incorrectly) in foreground mode, the library will automatically switch to background mode as soon as the screen goes off. As a result, the amount of time in the wrong mode will usually be limited and not have significant battery impact.