Before SDK 2.3.3-RAILS exit time was defined as absolute time since the last seen beacon, minus only last scan pause time. The exit condition was checked every second of the scan time. This solution is not inherently bad, but combined with using old API and somewhat crooked implementation, it had problems:
Since SDK 2.3.3-RAILS exit time is defined as a sum of scan times we haven’t seen given beacon. There is also grace period from the beginning of every scan when exit can’t be triggered, even though the exit time has passed. This solution results in:
Let’s consider behavior of SDK 2.3.3-RAILS on its default settings, while app is in background:
"scanner.exitTimeoutMillis": 40000,
"scanner.backgroundScanTime": 15000,
"scanner.backgroundWaitTime": 120000,
"scanner.exitBackgroundGraceMillis": 7500
Translated to graph this is:
Let’s assume the beacon was last seen 3s after the first scan cycle started:
Time needed for exit is 40s, so we need to finish the first cycle (12s), run second cycle (15s) and then exit is triggered in third cycle (after 13s of it). If the exit should appear in first 7.5s of the scan (grace time) it will be delayed till the end of the grace time.
In case of Android optimizing AlarmManager alerts the 120s wait time above may easily become 300s, thus prolonging exit times even further (up to 15 mins). The default settings are very defensive, resulting in stable exits even for worse phones, but may not be what you want. If your case needs quicker exits (but less consistency on older phones) experiment with lower exit timeout, e.g:
"scanner.exitTimeoutMillis": 20000
Proper solution is using new BT API combined with burst scanning (splitting scan time into sub-scans), plus grace time and possibly some hard-limited time of exit defined as absolute time since we’ve seen beacon.
And it’s coming soon!