I am new to BLE Beacons.
I have a BLE device that needs to be updated every once in a while when new data is available in my mobile app and vice-versa - when the BLE did something the app should know about.
In other words, the BLE device needs to be "synchronized" with the mobile app.
If the user opens the app, the BLE is synchronizing and everything is nice and shiny.
But I want this synchronization to work in the background, even if the user didn't open the app for 1, 2 days or even weeks so the next time the app is opened there will already be fresh data from the BLE device inside the app, and vice versa - the app will update the BLE for events that should happen even if the user didn't open the app (Like command the BLE to flash colors in 10 minutes).
I tried using the Android Bluetooth Library with RegionBootstrap, but I am confused about if Monitoring is even the way to go in my scenario.
This is the code inside my custom Application onCreate():
mBeaconManager = BeaconManager.getInstanceForApplication(this);
mBeaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout(IBEACON_PARSER_LAYOUT));
mBeaconManager.setRegionStatePersistenceEnabled(false);
mBeaconManager.setBackgroundBetweenScanPeriod(10000l);
mBeaconManager.setForegroundBetweenScanPeriod(10000l);
mBeaconManager.setBackgroundScanPeriod(1100l);
mBeaconManager.setForegroundScanPeriod(1100l);
region = new Region(getPackageName(),Identifier.parse(MY_BLE_BEACON_UID), null, null);
mRegionBootstrap = new RegionBootstrap(this, region);
This is my triggering events:
@Override
public void didEnterRegion(Region region) {
Log.e(TAG, "didEnterRegion: ");
synchronizeBleWithTheApp();
playSoundEnterRegion();
}
@Override
public void didExitRegion(Region region) {
Log.e(TAG, "didExitRegion: ");
playSoundExitRegion();
}
private void synchronizeBleWithTheApp() {
// 1) Check if there is any new data the BLE is interested in, if yes the app should push it to the BLE in the background.
// 2) Check if there is any new data in the BLE the app is interested in, if yes fetch it from the BLE in the background.
}
My questions are:
1) Should I even use monitoring in my case? I mean, I want to keep trying to synchronize even if the device is still in the region every X minutes. Does the RegionBootstrap suits in this case?
Right now, the didEnterRegion is triggered once and after 30~ seconds the onExitRegion is triggered, even though the BLE beacon is transmitting which is confusing for me.
2)if synchronizeBleWithTheApp() which is inside the custom Application class uses code in an Activity MainActivity class, does it mean I need the app to open that MainActivity? can I still trigger the synchronization in the background?
A few points:
If you want to get updates even when the beacon stays present, you must use ranging APIs in addition to RegionBootstrap. Start ranging by calling startRangingBeaconsInRegion(...)
in the didDetermineStateForRegion
callback.
You should not put any background code in an Activity class as Android may kill the Activity if not visible. The simplest place to put this code is in the custom Application class where you use RegionBootastrap (or in a custom class that is initialized and accessed from the custom Application class).
You also likely to need a foreground service to keep your app running more than 10 minutes in the background on Android 8+. The library makes it easy to add this without programming a foreground service of your own. See the library docs here: https://altbeacon.github.io/android-beacon-library/foreground-service.html
If you see detections stop in the background after a period of time on Android 7+ (causing a region exit event), you may need to add code to force long period background scanning: https://github.com/AltBeacon/android-beacon-library/pull/529
Finally, be careful of custom app killers on Chinese OEMs which may make it impossible to satisfy your requirements on phones made by these manufacturers. See here: http://www.davidgyoungtech.com/2019/04/30/the-rise-of-the-nasty-forks