I am working on an Application with the Android Beacon Library with Android 8+ and I need to do ranging in the background. For this purpose I use the nativly supported possibility to start the service as a foreground service. The Application should keep ranging, even when the application is closed! So implementing the BeaconConsumer Interface in an activity is not a good idea, beacuse if the Acitivity gets removed from the memory ranging will obviously stop. To work around this I created a custom application class and implemented a BeaconConsumer and started ranging in this component. So the custom application is the Consumer and handles the results in the onServiceConnect(...) Method. Do I need the BootstrapNotifier for my goal, or will it work like this? Will the Application keep ranging if the application is closed?
public class App extends Application implements BeaconConsumer {
onCreate(){
mbeaconManager =
org.altbeacon.beacon.BeaconManager.getInstanceForApplication(this);
mbeaconManager.setDebug(true);
// Create Notification for the Foreground Service
Intent intent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(
this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT
);
Notification notification = new
NotificationCompat.Builder(getApplicationContext(),CHANNEL_1_ID)
.setSmallIcon(R.drawable.icon)
.setContentTitle("\"Ranging runs in background!")
.setContentIntent(pendingIntent)
.build();
// Set Scanning Settings
mbeaconManager.enableForegroundServiceScanning(notification,
notificationID);
mbeaconManager.setEnableScheduledScanJobs(false);
mbeaconManager.setBackgroundBetweenScanPeriod(100);
mbeaconManager.setBackgroundScanPeriod(100);
}
public void onBeaconServiceConnect() {
mbeaconManager.removeAllRangeNotifiers();
mbeaconManager.addRangeNotifier(new RangeNotifier() {
public void didRangeBeaconsInRegion(...) {
// handle found beacons
}
mbeaconManager.startRangingBeaconsInRegion(...);
}
}
}
What you have looks fine. A few points for you to fully understand:
RegionBoostrap
is just a helper class designed to make it easier to set up automatic beacon detection on app startup using monitoring in an Application
class. You can do the same thing with beaconManager.bind(...)
then start monitoring in the onBeaconServiceConnected
callback.
Since you only care about ranging not monitoring (perfectly legitimate for your use case) then setting up manually like you did is a simpler way to go, as it avoids the unnecessary monitoring created by RegionBootstrap.
If you want your app to automatically resume to respond to beacon events, the key thing to do is put the code that sets this up in the onCreate method of a custom Application class. If you do that, it doesn't matter whether you use BootstrapNotifier
or BeaconConsumer
.
Why is Application.onCreate
so important?
The library sets up a number of hooks that will request an app restart for beacon scanning in a number of cases:
JobScheduler
instead of a Foreground ServiceBeaconService
(used when a foreground service is active on Android 8+ or always on Android 7 and earlier) is killed (due to memory pressure)In all of the above cases, what makes restarting beacon scanning possible is having code in Application.onCreate. That method is the very first app level code that gets executed when an Android app starts up. So if you set up your library initialization here, then the initialization will be done on any of the above events and you will resume beacon scanning as if you app never stopped running at all.