Implementing BootstrapNotifier on Activity instead of Application class
Asked Answered
M

1

0

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.

Sample code

Marino answered 16/1, 2016 at 6:36 Comment(0)
P
3

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();
  }
}
Passably answered 16/1, 2016 at 15:41 Comment(2)
Wow that's great news. So from what I have understood is that , I will make a Application class which will implement BootStrapNotifier and in the onCreate() of Application 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 the Activitytoo I would check whether the beacon detecting service was stopped and restart it.Marino
Apart from that I don't have to override the 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.