10
votes

I am working with iBeacons and using the AltBeacon library.

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

I would like my Android app to detect and generate an event when beacons enter and exit visibility. This works just fine fine with a single beacon using the library using methods.

public void **didEnterRegion**(Region region)

and

public void **didExitRegion**(Region region) 

My problem is when multiple beacons are visible at the same time. I am trying to maintain an array with all beacons visible. I want to generate an event each time a beacon enters and exits. The event should identify the beacon that generated the event by it's unique Identifier. My beacons are uniquely identifiable using the beacon.getIdentifiers() or (UUID, Major and Minor)

The problem is that the didExitRegion method does not get executed until all beacons exit the region.

Can anyone think of a simple way for me to achieve my goals using AltBeacon library?

Any suggestions would be greatly appreciated.

2
Can I ask you how do you test if a beacon exit the region? I need to write a program like this one you are writing... perhaps do you move your beacon to another place and check if the didExitRegion method was run? Thankspb772

2 Answers

23
votes

Two options:

  1. Set up a different region to match only each individual beacon, specifying all their identifiers, and monitor for each. You will get a different entry and exit callback for each region.

    Region region1 = new Region("myIdentifier1", Identifier.parse("2F234454-CF6D-4A0F-ADF2-F4911BA9FFA6"), Identifier.parse("1"), Identifier.parse("1"));        
    Region region2 = new Region("myIdentifier2", Identifier.parse("2F234454-CF6D-4A0F-ADF2-F4911BA9FFA6"), Identifier.parse("1"), Identifier.parse("2"));   
    
    beaconManager.startMonitoringBeaconsInRegion(region1);
    beaconManager.startMonitoringBeaconsInRegion(region2);    
    
  2. Enable ranging, and put code in the didRangeBeaconsInRegion callback to track individual beacons. You can use a java.util.HashMap to keep track of all beacons that are visible (with a timestamp for the latest time each was seen), and then if you haven't seen a beacon in, say, five seconds, you can remove the beacon from the HashMap and execute your exit logic for that beacon.

Option 1 is great for a small number of beacons where you know their identifiers up front. Option 2 is more involved, but better for a large number of beacons or if you do not know their identifiers in advance.

1
votes

/***************This Code for estimote Beacons *****************/

private  final Region ALL_ESTIMOTE_BEACONS_REGION = new Region("beaconall", null, null, null);

private BeaconManager beaconManager;

public  onCreate()
{

    beaconManager.connect(new BeaconManager.ServiceReadyCallback()
    {
        @Override
        public void onServiceReady()
        {
            Log.d("Lalit", "Beacon service Ready");

            beaconManager.startRanging(ALL_ESTIMOTE_BEACONS_REGION);
            beaconManager.startMonitoring(ALL_ESTIMOTE_BEACONS_REGION);
        }
    });
    beaconManager.setRangingListener(new BeaconManager.RangingListener() {
        @Override
        public void onBeaconsDiscovered(Region region, final List<Beacon> beacons) {

            int index = beacons.size();
            // UUID uuid = UUID.fromString("");
            if (beacons.size() > 0) {
                Beacon SelectedBeacon = beacons.get(index-1);

                Log.d("Lalit", "Beacon Id :- " + SelectedBeacon.getProximityUUID());
                Log.d("Lalit", "Beacon major :- " + SelectedBeacon.getMajor());
                Log.d("Lalit", "Beacon miner :- " + SelectedBeacon.getMinor());
                Log.d("Lalit", "Beacon total :- " + beacons.size());
                Log.d("Lalit","Distance :- "+ getDistance(SelectedBeacon.getRssi(),SelectedBeacon.getMeasuredPower()));
            }

        }
    });

    beaconManager.setMonitoringListener(new BeaconManager.MonitoringListener() {
        @Override
        public void onEnteredRegion(Region region, List<Beacon> list) {
            Calendar calendar = Calendar.getInstance();
            Date entertime = calendar.getTime();
            Log.d("Lalit", "Region Enter :- " + entertime);
            Log.d("List", "Region  UUID id :- " + region.getProximityUUID());
        }

        @Override
        public void onExitedRegion(Region region) {
            Calendar calendar = Calendar.getInstance();
            Date entertime = calendar.getTime();
            Log.d("Lalit", "Region exit :- " + entertime);
            Log.d("List", "Region  UUID id :- " + region.getProximityUUID());
        }
    });
}