Casper LI Casper LI - 5 months ago 19
Android Question

Cannot Update Distances of Multiple kBeacons at the Same Time

I am now trying to keep updating the distances of detected kBeacons and I use 3 kBeacons to do a test. I used the Android Beacon Library to detect the beacons but it gives me the same beacon through out the entire beacons collection in every

public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region)
call back.

06-22 12:39:26.740 20106-20164/hk.bds.ibeaconlocator D/MyBeacon: BC:6A:29:25:14:01
06-22 12:39:26.740 20106-20164/hk.bds.ibeaconlocator D/MyBeacon: BC:6A:29:25:14:01
06-22 12:39:26.740 20106-20164/hk.bds.ibeaconlocator D/MyBeacon: BC:6A:29:25:14:01
06-22 12:39:27.845 20106-20175/hk.bds.ibeaconlocator D/MyBeacon: BC:6A:29:27:A4:2D
06-22 12:39:27.845 20106-20175/hk.bds.ibeaconlocator D/MyBeacon: BC:6A:29:27:A4:2D
06-22 12:39:27.845 20106-20175/hk.bds.ibeaconlocator D/MyBeacon: BC:6A:29:27:A4:2D
06-22 12:39:28.955 20106-20193/hk.bds.ibeaconlocator D/MyBeacon: BC:6A:29:24:E1:DC
06-22 12:39:28.955 20106-20193/hk.bds.ibeaconlocator D/MyBeacon: BC:6A:29:24:E1:DC
06-22 12:39:28.955 20106-20193/hk.bds.ibeaconlocator D/MyBeacon: BC:6A:29:24:E1:DC
06-22 12:39:30.065 20106-20210/hk.bds.ibeaconlocator D/MyBeacon: BC:6A:29:24:E4:78
06-22 12:39:30.065 20106-20210/hk.bds.ibeaconlocator D/MyBeacon: BC:6A:29:24:E4:78
06-22 12:39:30.065 20106-20210/hk.bds.ibeaconlocator D/MyBeacon: BC:6A:29:24:E4:78


I expect it should give me 3 different mac addresses at a callback but it give me a different mac address in the next callback. How to solved?

The following shows you something about my program.
b1
,
b2
,
b3
is a object of
MyBeacon
.

@Override
public void onBeaconServiceConnect() {
//This method will be called when the Beacon Manager is binded.
beaconManager.setRangeNotifier( new RangeNotifier() {
@Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
// This method will be executed many times according to the size of the refresh interval.
// Try to update the distance of the devices
b1.updateDistance(beacons);
b2.updateDistance(beacons);
b3.updateDistance(beacons);
theNear = getMinOne(getMinOne(b1, b2), b3);

// Update Displays
updateDisplay();
}
});

try {
// Tells the BeaconService to start looking for beacons that match the passed Region object,
// and providing updates on the estimated mDistance every seconds while beacons in the Region are visible.
beaconManager.startRangingBeaconsInRegion(new Region("myRangingUniqueId", null, null, null));
} catch (RemoteException e) { /* Error is detected. */ }

}


Here is the
MyBeacon
class.

class MyBeacon {
private static final String TAG = "MyBeacon";
public String name;
public String macAddress;
public double distance = 0d; // initially the distance is 0.
//public double predistance = 0d;

// Display reference pointers.
public TextView displayName;
public TextView displayDistance;


public MyBeacon(String _name, String _macAddress, TextView _displayName, TextView _displayDistance) {
name = _name;
macAddress = _macAddress;
displayName = _displayName;
displayDistance = _displayDistance;
displayName.setText(name + " : ");
}

public boolean updateDistance(Beacon _beacon) {
if (_beacon.getBluetoothAddress().equals(this.macAddress)) {
distance = _beacon.getDistance(); // Calculate the distance based on RSSI.
return true;
} else
return false;
}

public void updateDistance(Collection<Beacon> beacons) {
for (Beacon theBeacon : beacons) {
Log.d(TAG, theBeacon.getBluetoothAddress());
if (updateDistance(theBeacon))
return;
}
distance = 0d;

}

public void updateDisplayDistance() {
String str;
if (distance == 0d)
str = "UNDETECTED";
else
str = String.format("%.4f", distance);
displayDistance.setText(str);
}

public String toString() {
String str = "";
str += "\n===================================";
str += "\nBeacon Name: " + this.name;
str += "\nMac Address: " + this.macAddress;
str += "\nDistance : " + this.distance;
str += "\n===================================";
return str;
}
}

Answer

By default, the Android Beacon Library will combine ranging results from multiple hardware beacons with different Mac addresses if they have the Same Identifier. I suspect that is what is going on here -- if all beacons have the same identifiers, you would see behavior like this.

To address the problem, you can easily configure the library to return distinct ranging results for each individual beacon Mac address even if the beacon identifiers are the same. To do so, simply add this line of code:

Beacon.setHardwareEqualityEnforced(true);
Comments