I am using altBeacon library for beacon detection. After checking out the sample codes on Beacon detection, they always implement the Interface BootstrapNotifier
on the Application
class instead of Activity
, which is used for detecting beacons in the background. However I have noticed that beacon detection in the background stops when BootstrapNotifier
is implemented on Activity
. I don't want my app to detect beacons as soon as it is launched hence I have not implemented BootStrapNotifier
on Application
class.I have a specific requirement where I want beacons to be detected only after a particular Activity
is launched and thereafter the beacons should always be detected in the background. Does the altBeacon library have any provisions for achieving this? Thanks.
Yes, it is possible to detect beacons in the background only after an Activity
starts, but you still need to make a custom Application
class that implements the BootstrapNotifier
.
The reason this is necessary is because of the Android lifecycle. An Activity
may be exited by backing out of it, going on to a new Activity
, or by the operating system terminating it in a low memory condition if you have taken it from the foreground.
In the low memory case, the entire application, including the Application
class instance (and the beacon scanning service) is terminated along with the Activity
. This case is completely beyond your control, but the Android Beacon Library has code to automatically restart the application and the beacon scanning service a few minutes after this happens.
The tricky part for your purposes is to figure out in the onCreate
method of the Application
class whether this this is an app restart (after low memory shutdown), or a first time launch of the app before the Activity
has ever been run.
A good way to do this is to store a timestamp in SharedPreferences for when your Activity
is launched.
So your Application
class might have code like this:
public void onCreate() {
...
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
long lastActivityLaunchTime = prefs.getLong("myapp_activity_launch_time_millis", 0l);
if (lastActivityLaunchTime > System.currentTimeMillis()-SystemClock.elapsedRealtime() ) {
// If we are in here we have launched the Activity since boot, and this is a restart
// after temporary low memory shutdown. Need to start scanning
startBeaconScanning();
}
}
public void startBeaconScanning() {
Region region = new Region("backgroundRegion",
null, null, null);
mRegionBootstrap = new RegionBootstrap(this, region);
mBackgroundPowerSaver = new BackgroundPowerSaver(this);
}
In your Activity
you will also need code to detect it is a first launch, and if so, start the scanning from there.
public void onCreate() {
...
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
long lastActivityLaunchTime = prefs.getLong("myapp_activity_launch_time_millis", 0l);
if (lastActivityLaunchTime < System.currentTimeMillis()-SystemClock.elapsedRealtime() ) {
// This is the first Activity launch since boot
((MyApplication) this.getApplicationContext()).startBeaconScanning();
SharedPreferences.Editor prefsEditor = prefs.edit();
prefsEditor.putLong("myapp_activity_launch_time_millis", System.currentTimeMillis());
prefsEditor.commit();
}
}
didEnterRegion()
in the Application
class(Leaving it blank) and override the didEnterRegion()
of the Activity
only to do want I want to do when a beacon is detected(Which is the main logic that I want to execute only from the Activity
)? –
Marino © 2022 - 2024 — McMap. All rights reserved.
Application
class which will implementBootStrapNotifier
and in theonCreate()
ofApplication
class I will have to check whether the beacon detecting service was stopped(Because of low memory termination) and if it was stopped I would simply restart it. And in theActivity
too I would check whether the beacon detecting service was stopped and restart it. – Marino