Gkapoor
Gkapoor

Reputation: 850

Why didRangeBeaconsInRegion called multiple times?

I’m using Android Beacon Library(AltBeacon SDK) in one of my project. My requirement is to show some checkin notification If user enter into the beacon range and checkout notification If exit the beacon range but the issue I’m facing is I’m keep getting the notifications i.e. didRangeBeaconsInRegion(Collection beacons, Region region) called multiple times. Is there any way that this function should call only once when the app come in range of beacon?

public class BeaconMonitoringService extends Service implements BootstrapNotifier, BeaconConsumer, RangeNotifier {



private static final String TAG = "BeaconMonitoringService";



private BeaconManager beaconManager;



@SuppressWarnings("unused")

private RegionBootstrap regionBootstrap;

@SuppressWarnings("unused")

private BackgroundPowerSaver backgroundPowerSaver;

private Region region;



@Override

public void onCreate() {

    super.onCreate();

    beaconSession = new BeaconSession(this);

    beaconManager = BeaconManager.getInstanceForApplication(this);

    beaconManager.getBeaconParsers().clear();



    beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));

    region = new Region("MyBeacon", Identifier.parse("0800200C9A66"), null, null);

    regionBootstrap = new RegionBootstrap(this, region);

    beaconManager.setBackgroundMode(true);

    backgroundPowerSaver = new BackgroundPowerSaver(this);

    beaconManager.bind(this);

}



@Override

public void didEnterRegion(Region region) {

    try {

        Log.d(TAG, "Did Enter Region.");

        beaconManager.startRangingBeaconsInRegion(region);

    } catch (RemoteException e) {

        if (BuildConfig.DEBUG) Log.d(TAG, "Can't start ranging");

    }

}



@Override

public void didExitRegion(Region region) {

    try {

        Log.d(TAG, "Did Exit Region");

    } catch (RemoteException e) {

        if (BuildConfig.DEBUG) Log.d(TAG, "Can't start ranging");

    }

}



@Override

public void didDetermineStateForRegion(int state, Region region) {

    switch (state) {

        case MonitorNotifier.INSIDE:

            Log.d(TAG, "INSIDE");

            didEnterInRegion = true;

            break;

        case MonitorNotifier.OUTSIDE:

            Log.d(TAG, "OUTSIDE");

            didEnterInRegion = false;

            break;

        default:

            didEnterInRegion = false;

            Log.d(TAG, "state" + state);

            break;

    }



}



@Override

public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {

    if (beacons.size() > 0) {

            for (Beacon beacon : beacons) {



             if (beacon.getId1().equals(Identifier.parse("0800200C9A66")) && beacon.getDistance() < 1.0) {

                         sendNotification(beacon);

                    }

            }

    }

}



@Override

public void onBeaconServiceConnect() {

    beaconManager.addRangeNotifier(this);

    try {

        beaconManager.startRangingBeaconsInRegion(region);

    } catch (RemoteException e) {

    }

}



@Override

public IBinder onBind(Intent intent) {

    return null;

}



@Override

public void onDestroy() {

    beaconManager.unbind(this);

    super.onDestroy();

}

}

Upvotes: 0

Views: 631

Answers (1)

davidgyoung
davidgyoung

Reputation: 64941

The didRangeBeaconsInRegion is designed to fire regularly at the end of each scan cycle (by default every ~ 1 second) to tell you which beacons were seen over that period.

If you only want an event to fire once fore each beacon detected you can create a class variable to hold a flag indicating whether or not you have processed each beacon already.

Like this:

// Put this at your class level
Set<String> mBeaconsProcessed = new HashSet<>();

...

// Put this code inside your didRangeBeaconsInRegion method

// Only process this beacon if we have not done so before
if (!mBeaconsProcessed.contains(beacon.toString)) {
    if (beacon.getId1().equals(Identifier.parse("0800200C9A66")) && beacon.getDistance() < 1.0) {
         sendNotification(beacon);
         // Mark this beacon as having already been processed.
         mBeaconsProcessed.put(beacon.toString));
         }
    }
}

Upvotes: 0

Related Questions