Search code examples
ibeacon-androidaltbeaconandroid-ibeacon

background beacon detection failing some times


using the altbeacon lib in the background it only detects the beacons only some of the times or at least only fires the app to the frontground only some times. Below is the logs when it doesn't detect and when it detected well.

04-20 17:10:07.335  24817-24817/com.mobinteg.ibeacon D/CycledLeScanner﹕ cancel wakeup alarm: PendingIntent{422554f0: android.os.BinderProxy@42255480}
    04-20 17:10:07.365  24817-24817/com.mobinteg.ibeacon D/CycledLeScanner﹕ Set a wakeup alarm to go off in 300000 ms: PendingIntent{42256498: android.os.BinderProxy@42256428}
    04-20 17:10:07.925  24817-24817/com.mobinteg.ibeacon D/CycledLeScanner﹕ starting a new scan cycle
    04-20 17:10:07.925  24817-24817/com.mobinteg.ibeacon D/CycledLeScanner﹕ starting a new bluetooth le scan
    04-20 17:10:07.925  24817-24817/com.mobinteg.ibeacon D/BluetoothAdapter﹕ startLeScan(): null
    04-20 17:10:07.945  24817-24833/com.mobinteg.ibeacon D/BluetoothAdapter﹕ onClientRegistered() - status=0 clientIf=5
    04-20 17:10:07.955  24817-24817/com.mobinteg.ibeacon D/CycledLeScanner﹕ Waiting to stop scan cycle for another 1100 milliseconds
    04-20 17:10:07.965  24817-24817/com.mobinteg.ibeacon D/CycledLeScanner﹕ cancel wakeup alarm: PendingIntent{42256498: android.os.BinderProxy@42256428}
    04-20 17:10:07.985  24817-24817/com.mobinteg.ibeacon D/CycledLeScanner﹕ Set a wakeup alarm to go off in 300000 ms: PendingIntent{422577d0: android.os.BinderProxy@42257760}
    04-20 17:10:07.985  24817-24817/com.mobinteg.ibeacon D/CycledLeScanner﹕ Scan started
    04-20 17:10:08.765  24817-24832/com.mobinteg.ibeacon D/BluetoothAdapter﹕ onScanResult() - Device=D6:06:36:3A:71:B3 RSSI=-63
    04-20 17:10:08.765  24817-24832/com.mobinteg.ibeacon D/CycledLeScannerForJellyBeanMr2﹕ got record
    04-20 17:10:08.765  24817-25200/com.mobinteg.ibeacon D/BeaconParser﹕ This is not a matching Beacon advertisement. (Was expecting be ac.  The bytes I see are: 0201041bff4c000215ebefd08370a247c89837e7b5634df52400010001cb5f00000000000000000000000000000000000000000000000000000000000000
    04-20 17:10:08.765  24817-25200/com.mobinteg.ibeacon D/BeaconParser﹕ This is a recognized beacon advertisement -- 02 15 seen
    04-20 17:10:08.765  24817-25200/com.mobinteg.ibeacon D/BeaconService﹕ beacon detected multiple times in scan cycle : id1: ebefd083-70a2-47c8-9837-e7b5634df524 id2: 1 id3: 1
    04-20 17:10:08.765  24817-25200/com.mobinteg.ibeacon D/BeaconService﹕ beacon detected : id1: ebefd083-70a2-47c8-9837-e7b5634df524 id2: 1 id3: 1
    04-20 17:10:08.775  24817-25200/com.mobinteg.ibeacon D/BeaconService﹕ looking for ranging region matches for this beacon
    04-20 17:10:08.985  24817-24817/com.mobinteg.ibeacon D/CycledLeScanner﹕ Waiting to stop scan cycle for another 71 milliseconds
    04-20 17:10:08.985  24817-24817/com.mobinteg.ibeacon D/CycledLeScanner﹕ cancel wakeup alarm: PendingIntent{422577d0: android.os.BinderProxy@42257760}
    04-20 17:10:08.995  24817-24817/com.mobinteg.ibeacon D/CycledLeScanner﹕ Set a wakeup alarm to go off in 300000 ms: PendingIntent{4225b930: android.os.BinderProxy@4225b8c0}
    04-20 17:10:09.065  24817-24817/com.mobinteg.ibeacon D/CycledLeScanner﹕ Done with scan cycle
    04-20 17:10:09.065  24817-24817/com.mobinteg.ibeacon D/CycledLeScanner﹕ stopping bluetooth le scan
    04-20 17:10:09.075  24817-24817/com.mobinteg.ibeacon D/BluetoothAdapter﹕ stopLeScan()
    04-20 17:10:09.085  24817-24817/com.mobinteg.ibeacon D/CycledLeScanner﹕ Normalizing between scan period from 15000 to 14915
    04-20 17:10:09.085  24817-24817/com.mobinteg.ibeacon D/CycledLeScannerForJellyBeanMr2﹕ Waiting to start next bluetooth scan for another 14915 milliseconds

when it fires well it appears as:

04-20 17:10:56.225  24817-24817/com.mobinteg.ibeacon D/CycledLeScanner﹕ starting a new scan cycle
04-20 17:10:56.225  24817-24817/com.mobinteg.ibeacon D/CycledLeScanner﹕ starting a new bluetooth le scan
04-20 17:10:56.225  24817-24817/com.mobinteg.ibeacon D/BluetoothAdapter﹕ startLeScan(): null
04-20 17:10:56.235  24817-24833/com.mobinteg.ibeacon D/BluetoothAdapter﹕ onClientRegistered() - status=0 clientIf=5
04-20 17:10:56.245  24817-24817/com.mobinteg.ibeacon D/CycledLeScanner﹕ Waiting to stop scan cycle for another 1100 milliseconds
04-20 17:10:56.245  24817-24817/com.mobinteg.ibeacon D/CycledLeScanner﹕ cancel wakeup alarm: PendingIntent{422922d0: android.os.BinderProxy@42292260}
04-20 17:10:56.285  24817-24817/com.mobinteg.ibeacon D/CycledLeScanner﹕ Set a wakeup alarm to go off in 300000 ms: PendingIntent{42293608: android.os.BinderProxy@42293598}
04-20 17:10:56.285  24817-24817/com.mobinteg.ibeacon D/CycledLeScanner﹕ Scan started
04-20 17:10:56.995  24817-24832/com.mobinteg.ibeacon D/BluetoothAdapter﹕ onScanResult() - Device=D6:06:36:3A:71:B3 RSSI=-68
04-20 17:10:56.995  24817-24832/com.mobinteg.ibeacon D/CycledLeScannerForJellyBeanMr2﹕ got record
04-20 17:10:56.995  24817-24865/com.mobinteg.ibeacon D/BeaconParser﹕ This is not a matching Beacon advertisement. (Was expecting be ac.  The bytes I see are: 0201041bff4c000215ebefd08370a247c89837e7b5634df52400010001cb6100000000000000000000000000000000000000000000000000000000000000
04-20 17:10:57.005  24817-24865/com.mobinteg.ibeacon D/BeaconParser﹕ This is a recognized beacon advertisement -- 02 15 seen
04-20 17:10:57.005  24817-24865/com.mobinteg.ibeacon D/BeaconService﹕ beacon detected multiple times in scan cycle : id1: ebefd083-70a2-47c8-9837-e7b5634df524 id2: 1 id3: 1
04-20 17:10:57.015  24817-24865/com.mobinteg.ibeacon D/BeaconService﹕ beacon detected : id1: ebefd083-70a2-47c8-9837-e7b5634df524 id2: 1 id3: 1
04-20 17:10:57.015  24817-24865/com.mobinteg.ibeacon D/Callback﹕ attempting callback via intent: ComponentInfo{com.mobinteg.ibeacon/org.altbeacon.beacon.BeaconIntentProcessor}
04-20 17:10:57.025  24817-24865/com.mobinteg.ibeacon D/BeaconService﹕ looking for ranging region matches for this beacon
04-20 17:10:57.035  24817-25231/com.mobinteg.ibeacon D/BeaconIntentProcessor﹕ got an intent to process
04-20 17:10:57.035  24817-25231/com.mobinteg.ibeacon D/BeaconIntentProcessor﹕ got monitoring data
04-20 17:10:57.045  24817-25231/com.mobinteg.ibeacon D/BeaconIntentProcessor﹕ Calling monitoring notifier: com.mobinteg.ibeacon.Background@420719f8
04-20 17:10:57.045  24817-25231/com.mobinteg.ibeacon D/testbackground﹕ Region id1: null id2: null id3: null
04-20 17:10:57.045  24817-25231/com.mobinteg.ibeacon D/testbackground﹕ Got a didEnterRegion call
04-20 17:10:57.285  24817-24817/com.mobinteg.ibeacon D/CycledLeScanner﹕ Waiting to stop scan cycle for another 63 milliseconds
04-20 17:10:57.285  24817-24817/com.mobinteg.ibeacon D/CycledLeScanner﹕ cancel wakeup alarm: PendingIntent{42293608: android.os.BinderProxy@42293598}
04-20 17:10:57.295  24817-24817/com.mobinteg.ibeacon D/CycledLeScanner﹕ Set a wakeup alarm to go off in 300000 ms: PendingIntent{422a1e20: android.os.BinderProxy@422a1db0}
04-20 17:10:57.355  24817-24817/com.mobinteg.ibeacon D/CycledLeScanner﹕ Done with scan cycle
04-20 17:10:57.355  24817-24817/com.mobinteg.ibeacon D/CycledLeScanner﹕ stopping bluetooth le scan
04-20 17:10:57.355  24817-24817/com.mobinteg.ibeacon D/BluetoothAdapter﹕ stopLeScan()

the code is the follow

public class Background extends Application implements BootstrapNotifier{

    private static final String TAG = "testbackground";//".MyApplicationName";
    private static final String UUID = "EBEFD08370A247C89837E7B5634DF524";//"ebefd083-70a2-47c8-9837-e7b5634df524";//
    //private BackgroundPowerSaver backgroundPowerSaver;//to able battery saving
    private RegionBootstrap regionBootstrap;
    private BeaconManager beaconManager;


    @Override
    public void onCreate() {
        super.onCreate();
        beaconManager.setDebug(true);
        // Simply constructing this class and holding a reference to it in your custom Application class
        // enables auto battery saving of about 60%
        //backgroundPowerSaver = new BackgroundPowerSaver(this);
        Region region = new Region(".Background",null,null,null);
        beaconManager = BeaconManager.getInstanceForApplication(this);
        beaconManager.getBeaconParsers().add(new BeaconParser()
                .setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25"));
        try{
            // set the duration of the scan to be 1.1 seconds
            beaconManager.setBackgroundScanPeriod(1100l);
            // set the time between each scan to be 1 hour (3600 seconds)//50000l
            beaconManager.setBackgroundBetweenScanPeriod(15000l);//3600000l
            beaconManager.updateScanPeriods();
            //beaconManager.startMonitoringBeaconsInRegion(region);

        }  catch (RemoteException e) {
            //Log.e(TAG, "Cannot talk to service");
        }

        // wake up the app when any beacon is seen (you can specify specific id filers in the parameters below)
        regionBootstrap = new RegionBootstrap(Background.this, region);

    }

    @Override
    public void didDetermineStateForRegion(int state, Region region) {
        // Don't care
        Log.d(TAG, "Region " + region.toString());
    }

    @Override
    public void didEnterRegion(Region arg0) {
        Log.d(TAG, "Got a didEnterRegion call");
        // This call to disable will make it so the activity below only gets launched the first time a beacon is seen (until the next time the app is launched)
        // if you want the Activity to launch every single time beacons come into view, remove this call.
        //regionBootstrap.disable();
        Intent intent = new Intent(this, MainActivity.class);
        // IMPORTANT: in the AndroidManifest.xml definition of this activity, you must set android:launchMode="singleInstance" or you will get two instances
        // created when a user launches the activity manually and it gets launched from here.
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        //beaconManager.setBackgroundMode(false);
        this.startActivity(intent);
    }

    @Override
    public void didExitRegion(Region arg0) {
        // Don't care
    }


}

Solution

  • The two log excerpts both show normal operations. In the first case, a beacon is detected when the device is already inside the beacon region (e.g. a beacon is already visible). The didEnterRegion callback is therefore not called.

    In the second case, a beacon is detected when the device is not already inside the beacon region (e.g. when no beacons are currently visible). The didEnterRegion callback is therefore called.

    In order for you to get a second callback to the didEnterRegion method, you must wait long enough for the device to detect that no beacons are around. Based on the background settings of scanning for 1.1 seconds every 15 seconds, this can take 21.1 seconds to happen (15 seconds + 1.1 seconds + 5 seconds to disappear). So you must turn off a beacon for just over 20 seconds (or move the Android device away from all beacons for this time) before you can get a second call to didEnterRegion.