Proximity Location

Hello folks,
I need an help.
I building an app with Proximity Location as the indoor does not have SDK yet for Android.
I’m using Estimote sample code . In fact I just need to be sure if a user is at an alley or another.
My issue I’m not receiving notification for the correct beacon .The app still sending notification for all three beacons even if the user is not moving.
When the user moves ,the notification sent by the app does not corresponds to the beacon located in the alley.
Below is the code
public class MainActivity extends AppCompatActivity {

private static final Map<String, List<String>> PLACES_BY_BEACONS;


static {
    Map<String, List<String>> placesByBeacons = new HashMap<>();
    placesByBeacons.put("16923:52747", new ArrayList<String>() {{
        add("Sandwiches");
           add("Green & Green Salads");
             add("Mini Panini");
      
    }});
    placesByBeacons.put("28592:17738", new ArrayList<String>() {{
        add("Mini Panini");
        add("Green & Green Salads");
        add("Heavenly Sandwiches");
    }});
    placesByBeacons.put("14286:46651", new ArrayList<String>() {{
        add("candy");
        add("coke");
        add("juice");
    }});
    PLACES_BY_BEACONS = Collections.unmodifiableMap(placesByBeacons);
}

private List<String> placesNearBeacon(Beacon beacon) {

    String beaconKey = String.format("%d:%d", beacon.getMajor(), beacon.getMinor());
    if (PLACES_BY_BEACONS.containsKey(beaconKey)) {
        return PLACES_BY_BEACONS.get(beaconKey);
    }
    return Collections.emptyList();
}

private BeaconManager beaconManager;
private Region region;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    beaconManager = new BeaconManager(this);
    beaconManager.setRangingListener(new BeaconManager.RangingListener() {
        @Override
        public void onBeaconsDiscovered(Region region, List<Beacon> list) {
            if (!list.isEmpty()) {
                Beacon nearestBeacon = list.get(0);
                List<String> places = placesNearBeacon(nearestBeacon);
                               Toast.makeText(getApplicationContext(),places.toString(),Toast.LENGTH_SHORT).show();
            }
        }
    });

//fromString(“contain the uuid of beacon) in the estimote cloud
region = new Region(“ranged region”, UUID.fromString(”"), null, null);
}

@Override
protected void onResume() {
    super.onResume();

    SystemRequirementsChecker.checkWithDefaultDialogs(this);

    beaconManager.connect(new BeaconManager.ServiceReadyCallback() {
        @Override
        public void onServiceReady() {
            beaconManager.startRanging(region);
        }
    });
}

@Override
protected void onPause() {
    beaconManager.stopRanging(region);

    super.onPause();
}

}

Hello Franceska,
I believe in the onBeaconsDiscovered method, you can’t just take the first beacon. You need to sort the list of beacons by distance, or simply find the closest one from the list:

public void onBeaconsDiscovered(Region region, List<Beacon> list) {
       Beacon nearestBeacon = findNearestBeacon(beaconsOfInterest);
}
 
...

private static Beacon findNearestBeacon(List<Beacon> beacons) {
    Beacon nearestBeacon = null;
    double nearestBeaconsDistance = -1;
    for (Beacon beacon : beacons) {
        double distance = Utils.computeAccuracy(beacon);
        if (distance > -1 &&
                (distance < nearestBeaconsDistance || nearestBeacon == null)) {
            nearestBeacon = beacon;
            nearestBeaconsDistance = distance;
        }
    }

    Log.d(TAG, "Nearest beacon: " + nearestBeacon + ", distance: " + nearestBeaconsDistance);
    return nearestBeacon;
}

As you see Utils.computeAccuracy(beacon) returns the distance.

(This code is taken from the sample app, but sorting the whole list of beacons by distance can also be done easily).

One tip (which I mentioned already in the forum): When you do ranging (according to the demo code), you might noticed that the list of closest beacons might change every 300ms. This might happen because beacons send out their signal at different times as other beacons. If you implement a “low pass filter”, by buffering the beacons_id + distance + time, and then you are using all values <1000ms, you get a more stable result.

Philipp

Schneeweis.Technology

Thanks a lot for the tricks,you give me my birthday gift .I obtain better results.
As I would like to have a stable value because I need to present the true context to the user depending
the alley of the store the user is located.
When you mentioned “low pass filter”. I don’t have a clear idea for the implementation
of the algorithm.
Buffering the beacon +distance+time .What you mean by buffering?

If possible can you share with me the principles of the algorithm.

Thanks a million
FD

Hi Philipp1,
I don’t understand how you get it working, I always get a list of 1 beacon, the nearest one.
Can you explain me please?
Alain