Closed Whathecode closed 6 months ago
The specific time for region exit or non-deterministic, but is within predictable ranges. It is complex, so I wrote a blog post with a table a few years back which explains why this is so complex: http://www.davidgyoungtech.com/2017/08/07/beacon-detection-with-android-8
Look in the table for the number of seconds to detect a beacon disappearing.
To summarize the limitations:
Separately from scan cycling, BeaconManager.setRegionExitPeriod() decides how long after a beacon is not detected that a region exit event fires. This will always be at the end of a scan cycle, so the cycle times above affect this as well.
Finally, do not be confused by MIN_SCAN_JOB_INTERVAL_MILLIS. This does not affect scan cycles. It just keeps job scheduler runs in the foreground (generally one runs immediately after the other) from being so short that the hurt performance by restarting too often. There is a CycledLeScanner at a lower level that turns scans on and off to match the configured intervals.
@whatthecode I would welcome a PR for improving the documentation on this. But I am not sure the best way to document this given the complexity. I will note that with iOS Core Location (after which this library’s API is modeled for cross-platform purposes) there are similar complexities that affect the timing of region exits and they are totally undocumented! At least with open source you can look at the code and ask the developer questions. :)
Thank you for elaborating! 🙏 This clears some things up.
I'm still uncertain about the following:
If the library is configured to use a foreground service for scanning, the above limitation does not apply.
Our primary use case is having a constant foreground service running (we are doing continuous data collection).
The scan periods are otherwise respected, with the background variants used when the app is not visible and BackgroundPowerSaver is active.
Do I understand correctly that this means while the screen is on foregroundScanPeriod/foregroundBetweenScanPeriod
is used, and while it is off backgroundScanPeriod/backgroundBetweenScanPeriod
is used? Maybe my confusion stemmed from thinking that "foreground service" mapped to "foreground" scan, while this is not the case?
P.s. the documentation does not call updateScanPeriods()
after setting them. Is it needed? :) I might contribute PRs if we decide to continue using this library and it would open up more flexibility/use cases. However, I am currently also considering a more low-level library like SweetBlue with which I had success before integrating to other BLE devices.
Yes, foregroundScanPeriod and foregroundBetweenScanPeriod are applied if BackgroundPowerSaver determines an app activity is visible with the screen on. Otherwise backgroundScanPeriod and backgroundBetweenScanPeriod are applied.
Whether or not there is a foreground service is irrelevant to which scan period settings are active.
Generally there is no need to call updateScanPeriods(). The only case where you do is if you want to change these periods after scanning has already started. In this case making the call to updateScanPeriods() will apply the new periods immediately. Otherwise they will be applied at the next foreground/background transition.
Yes, if you want full control over scans, then you probably want to use raw Android APIs. This library is designed to make it easier to handle common beacon use cases.
I'm trying to figure out what determines when
didExitRegion
is called, since the documentation is severely lacking in this regard. For one, the documentation on foreground service seems to explain how you can callsetBackgroundScanPeriod
andsetBackgroundBetweenScanPeriod
, which from perusing the codebase seems entirely irrelevant, since when you are in foreground mode the relevant settings are the correspondingforeground
settings.Digging deeper into the code, since changing
foregroundScanPeriod
seemingly didn't have a meaningful effect in terms of whetherdidExitRegion
got called, or is non-deterministic at the very least, I discovered:So essentially, if you are in foreground mode, any value < 5 minutes (MIN_SCAN_JOB_INTERVAL_MILLIS) is ignored? Could somebody explain me how
foregroundScanPeriod
andforegroundBetweenScanPeriod
impactdidExitRegion
, if at all?I also later discovered the static
BeaconManager.setRegionExitPeriod()
(which is silently ignored if beacon manager is not yet initialized), which seems to be the main relevant setting which influences how long to wait before firingdidExitRegion
, but that wasn't obvious from the documentation/API at all. I'm still interested in understanding how the scan period settings impact this.