Search code examples
androidibeacon-androidaltbeaconandroid-ibeacon

It takes some minutes to start scanning on background mode (Using AltBeacons)


I'm trying to monitor beacons on background and foreground mode, by only assigning the first ID and then getting full UUID of the beacons detected.

Using the method didEnterRegion, the second ID of the region was null so what I did was to start ranging beacons when I enter to one region to detect which is that second ID.

public class BeaconListener extends Application implements BootstrapNotifier {
private static final String TAG = "BEACON TEST";
private RegionBootstrap regionBootstrap;
private MonitoringActivity monitoringActivity = null;
private Region mRegion;
private BeaconManager beaconManager;
private String UUID;
public void onCreate() {
    super.onCreate();
    beaconManager = BeaconManager.getInstanceForApplication(this);
    beaconManager.getBeaconParsers().add(new BeaconParser().
            setBeaconLayout("s:0-1=feaa,m:2-2=00,p:3-3:-41,i:4-13,i:14-19"));
    beaconManager.setBackgroundScanPeriod(1100);
    beaconManager.setBackgroundBetweenScanPeriod(0);
    beaconManager.setAndroidLScanningDisabled(true);

    beaconManager.setBackgroundMode(true);

    mRegion = new Region("Beacon", Identifier.parse("0xffffffffffffffffffff"), null, null);

    regionBootstrap = new RegionBootstrap(this, mRegion);

}

@Override
public void didEnterRegion(Region arg0) {
    // In this example, this class sends a notification to the user whenever a Beacon
    // matching a Region (defined above) are first seen.

    try {
        beaconManager.startRangingBeaconsInRegion(mRegion);
        beaconManager.setRangeNotifier(new RangeNotifier() {
            @Override
            public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region arg0) {
                try {
                    for (Beacon beacon : beacons) {
                          beaconManager.stopRangingBeaconsInRegion(mRegion);
                          sendNotification();
                    }
                } catch (Exception e) {
                    Log.i(TAG, e.getMessage());
                }
            }
        });

        beaconManager.startRangingBeaconsInRegion(mRegion);
        beaconManager.setBackgroundScanPeriod(1100);
        beaconManager.setBackgroundBetweenScanPeriod(0);
        beaconManager.setAndroidLScanningDisabled(true);
    } catch (RemoteException e) {    }
}

This works fine, and I can get the full UUID of the beacon/s that are detected but, when I kill the app or I put it on background mode, it takes some minutes (about 5) to restart the monitoring service. Is there any way to restart the service immediately after going to background or killing the app? When I connect the device to the charger it restarts the service and quickly finds the beacons again.

PS: when I talk about first ID and second ID I asume that UUID = ID1 + ID2


Solution

  • You are correct that it takes up to five minutes to restart scanning after a user kills an app using the Android Beacon Library. There is no way to configure this interval, but it can be changed in code if appropriate for your use case.

    Understand that when you kill an app with the task switcher, the OS will stop all processes associated with the app, including background services like the one the library uses to scan for beacons. The library restarts this scanning service using two different techniques:

    1. By listening for power connect/disconnect events.

    2. By using an AlarmManager to restart if five minutes have passed since the last time it was active.

    The second method is used both for cases where an app was killed with the task switcher and by the operating system due to a low memory condition. In the latter case, it would be inappropriate to restart immediately because a foreground app may need to evict other apps to use all system memory for some time. The Google Maps app often causes this when panning and zooming.

    The five minute interval was chosen simply because it is a reasonable time interval to expect a low memory condition to clear.

    While the five minute default is not configurable in the library, since it is open source, you can compile a modified version to set this to a shorter interval if you wish. The code to change is here. Understand, however, that this may negatively impact memory-hungry foreground apps.