How to get visible beacons from the RegionBootstrap AltBeacon method
Asked Answered
F

2

6

I'm using the example code on this page (http://altbeacon.github.io/android-beacon-library/samples.html) in the Starting an App in the Background section and I've got a working app.

It detects whenever a beacon is in range even on background.

The problem is I need to know which beacon is it (UUID, Major, Minor) to then match it against my local database and throw a notification with the app still on background.

The didEnterRegion(Region region) function only has a matchesBeacon method, and I've tried doing the following to identify which of the beacons is being seen but it's throwing a NullPointerException:

public class SightSeeing extends Activity implements BootstrapNotifier, RangeNotifier {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    Region region = new Region("sightRegion", null, null, null);
    regionBootstrap = new RegionBootstrap(this, region);

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

    BeaconManager.getInstanceForApplication(this).setRangeNotifier(this);

}

@Override
public void didEnterRegion(Region region) {

    regionBootstrap.disable();

    BeaconManager.getInstanceForApplication(this).setRangeNotifier(this);

    try {
        BeaconManager.getInstanceForApplication(this).startRangingBeaconsInRegion(region);
    }
    catch (RemoteException e) {
        Log.e(TAG, "Can't start ranging");
    }

 }


@Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
    if (beacons.size() > 0) {
        Iterator<Beacon> beaconIterator = beacons.iterator();
        while (beaconIterator.hasNext()) {
            Beacon beacon = beaconIterator.next();
            //check if beacon exists in our DB and throw notification
        }
    }
}

Am I missing something obvious or isn't this possible with this library?

EDIT:

I've updated the code sample to give you guys a broader idea and I've tried implementing the suggestion by FOliveira without any success.

EDIT2:

Updated code to reflect the davidgyoung's suggestion. Still no luck. I have a Log.d() right on the first line of the didRangeBeaconsInRegion() function and it isn't being called.

I've tried adding BeaconManager.getInstanceForApplication(this).setRangeNotifier(this); before the try/catch block and the result is the same.

Did I implement the suggestion wrong or is there any other way to get this working?

Fixed answered 10/9, 2014 at 14:39 Comment(2)
Do you know that didEnterRegion is being called? Try adding a debug line at the top of that. Obviously if it doesn't get called, you won't be able to successfully start ranging with this setup.Klaus
did you solve this problem? Im facing the same problem.Koren
K
4

If you want the app to launch itself on beacon detection, then the RegionBootstrap is the easiest way to go. In order to combine this with Ranging needed to detect individual beacons, then add code in your didEnterRegion method like this:

try {
    BeaconManager.getInstanceForApplication(this).startRangingBeaconsInRegion(region);
} 
catch (RemoteException e) { 
    Log.e(TAG, "Can't start ranging");
}

Then implement a ranging callback like you have.

You also need to remove the code below, which is probably what is causing your NullPointerException, because the :

for(int i=0; i< beaconsList.size(); i++) {
    Beacon b = new Beacon.Builder()
            .setId1(beaconsList.get(i).get("uuid"))
            .setId2(beaconsList.get(i).get("major"))
            .setId3(beaconsList.get(i).get("minor"))
            .build();

    if(region.matchesBeacon(b)) {
        //get info from DB and throw notification
    }
 }

EDIT: I have updated the library's reference application to show how this can be done successfully. See here: https://github.com/AltBeacon/android-beacon-library-reference/blob/master/src/org/altbeacon/beaconreference/BeaconReferenceApplication.java

Klaus answered 10/9, 2014 at 16:16 Comment(7)
I've tried implementing your suggestion as reflected in the original question now. My didRangeBeaconsInRegion() is never called. Did I do something wrong or am I missing something?Zeuxis
I do not see anything else wrong with your code, and I have verified that this works in our reference app. I will post an updated copy of our reference app tomorrow and add a comment linking to it for you to try.Klaus
I already got it working correctly :) thanks for your supportZeuxis
For the record, I have updated the reference app to show how this can be done successfully. See here: github.com/AltBeacon/android-beacon-library-reference/blob/…Klaus
I Have tried to do the same but I got an exception when I launch startRangingBeaconsInRegion(region); : Can't start ranging - The BeaconManager is not bound to the service. Call beaconManager.bind(BeaconConsumer consumer) and wait for a callback to onBeaconServiceConnect()Suzette
@Drakkin, you may want to open a new question showing your code so we know exactly what you are doing. It is difficult to know what is the same about what you are doing vs. above and what might be different.Klaus
I have fixed my problem using 2 differents RegionBootstrap for detecting my 2 iBeacons. regionBootstrap = new RegionBootstrap(this, new Region("EB", Identifier.parse("EBEFD083-70A2-47C8-9837-E7B5634DF524"), null, null)); regionBootstrap2 = new RegionBootstrap(this, new Region("A7", Identifier.parse("A7AE2EB7-1F00-4168-B99B-A749BAC1CA64"), null, null)); I didn't mentionned it but it is for background detection in the Application class.Suzette
M
0

you can implement RangeNotifier interface and you can access all the beacon information captured in the public void didRangeBeaconsInRegion(Collection<Beacon> Beacons, Region region) method of that interface. Hope i got the question right

Marcos answered 10/9, 2014 at 15:21 Comment(5)
I've implemented RangeNotifier in the main class but it isn't being called by the RegionBootstrap on the background.Zeuxis
I've updated my answer to reflect your suggestion, because it didn't work. Let me know if you meant a different thing because it isn't working yet.Zeuxis
Oh ok, i understand now your problem! I think you can't actually get the information from the RegionBootstrap, instead, you can try to create regions matching your specific beacons Region region = new Region("NameOfTheBeacon", "UUID", "Major", "Minor"); which will only trigger on your specific regions (Which you can define several as far as i know). This is just a Hint because in my applications i have a service that runs in background that implements RangeNotifier and i check all the available beacons.Marcos
How did you implement that service without using RegionBootstrap? That looks exactly what I need.Zeuxis
First of all you need to put to work without the background! Try to implement BeaconConsumer Interface and do a BeaconManager.bind(this); in your onCreate method. After that, move your code of onCreate to the public void onBeaconServiceConnect() new method. This works for me, on a running application.Marcos

© 2022 - 2024 — McMap. All rights reserved.