I am using altbeacon library for detecting iBeacon. It shows all beacons on first scanning then some beacons are missing out.
This is my situation:
I have 7 beacons, on first scanning the app detecting all beacons.
If I again try to scan for beacons it shows only 4.
How can I fix this? I am adding my code below.
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
beaconManager = BeaconManager.getInstanceForApplication(this);
beaconManager.getBeaconParsers().add(new BeaconParser().
setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));
backgroundPowerSaver = new BackgroundPowerSaver(this);
beaconManager.bind(this);
return START_STICKY;
}
#Override
public void onBeaconServiceConnect() {
RangeNotifier rangeNotifier = new RangeNotifier() {
#Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
if (beacons.size() > 0)
{
Beacon firstBeacon = beacons.iterator().next();
String beaconID = String.valueOf(firstBeacon.getId3());
Log.v("beacons",""+beaconID);
}
}
};
try {
beaconManager.startRangingBeaconsInRegion(new Region("buuid", Identifier.parse(buuid), null, null));
beaconManager.addRangeNotifier(rangeNotifier);
}
catch (RemoteException e) { }
}
The code is currently printing out the third identifier of the first beacon seen:
if (beacons.size() > 0) {
Beacon firstBeacon = beacons.iterator().next();
String beaconID = String.valueOf(firstBeacon.getId3());
Log.v("beacons",""+beaconID);
}
It is NOT printing out a count of beacons seen. If you want it to print out the count of beacons seen, do this.
Log.v("beacon count", ""+beacons.count);
**EDIT: ** Also, understand that if you only look at the first beacon when there are multiple around, it may not behave consistently due to indeterminate ordering of the detections. You really need to see a list of all beacon ids detected, so use a loop like this:
Log.v("beacons", "Here are the beacons I see:");
for (Beacon beacon: beacons) {
String beaconID = String.valueOf(beacon.getId3());
Log.v("beacons","beacon id: "+beaconID);
}
The above will print a list like this:
Here are the beacons I see:
3
4
5
The order of identifiers may be different from one run to a next, but the list of the identifiers should generally be the same as long as all the beacons remain around.
Related
I'm working on a simple beacon proximity app using AltBeacon library from here https://altbeacon.github.io/android-beacon-library/samples.html.
I am experimenting with the sample code provided on the above website, however, each time I run the app it only goes to addRangingNotifier() method. If it detected the beacon it would go log the beacon size.
private Region defaultRegion = null;
defaultRegion = new Region("BeaconIdentifier", Identifier.fromUuid(java.util.UUID.fromString(UUID)), null, null);
beaconManager = BeaconManager.getInstanceForApplication(this);
beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));
beaconManager.bind(this);
#Override
public void onBeaconServiceConnect() {
beaconManager.addRangeNotifier(new RangeNotifier() {
#Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
if (beacons.size() > 0) {
Log.d("MainInfo","Beacon List Size " + beacons.size());
}else{
Log.d("MainInfo","Beacon Empty");
}
}
});
try {
beaconManager.startRangingBeaconsInRegion(defaultRegion);
} catch (RemoteException e) {}
}
I can receive the beacon size around of me.
I test the two device(A : Samsung galaxy J510-Marshmellow/B: Samsung galaxy J7-Nougat), B scan the beacon and print Beacon List Size, but, A can't scan the beacon and print Beacon Empty.
So I test same Marshmellow device, but I can't find it.
Are there any codes that should be added depending on the operating system?
The most likely thing wrong is that the UUID specified does not match your beacon. Try replacing this code:
Identifier.fromUuid(java.util.UUID.fromString(UUID))
With
null
To match all beacons. If this fixes it, replace the UUID with the one you are out of the detected beacon.
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
try {
Beacon beacon = new Beacon.Builder()
.setId1("2f234454-cf6d-4a0f-adf2-f4911ba9ffa6") // UUID for beacon
.setId2("1") // Major for beacon
.setId3("5") // Minor for beacon
.setManufacturer(0x004C) // Radius Networks.0x0118 Change this for other beacon layouts//0x004C for iPhone
.setTxPower(-56) // Power in dB
.setDataFields(Arrays.asList(new Long[]{0l})) // Remove this for beacon layouts without d: fields
.build();
BeaconParser beaconParser = new BeaconParser()
.setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24");
BeaconTransmitter beaconTransmitter = new BeaconTransmitter(getApplicationContext(), beaconParser);
beaconTransmitter.startAdvertising(beacon, new AdvertiseCallback() {
#Override
public void onStartFailure(int errorCode) {
Log.e("tag", "Advertisement start failed with code: " + errorCode);
}
#Override
public void onStartSuccess(AdvertiseSettings settingsInEffect) {
Log.i("tag", "Advertisement start succeeded.");
}
});
}
catch(Exception o)
{
}
}
I am using AltBeacon Library to turn my phone to a beacon.I am getting in my adb logcat avdertisment start succeeded. However I want to detect other phones now that are acting as a beacon, how can I achieve that?
Detecting beacons with the Android Beacon Library is simple. See the Ranging Sample Code section on this page: http://altbeacon.github.io/android-beacon-library/samples.html
As the example code linked above show, you will get a callback approximately once per second with a list of all beacons visible over that time in a method that looks like this:
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
// The beacons collection contains all beacons detected in the past second
}
I am working on Android beacon app with PiBeacon as a beacon device.
I have setup Respberry Pi As Beacon Device as given on adfruit website.
I can see that PiBeacon is transmitting by using other BLE Scanner application available on Play Store.
I have download the Altbeacon and configure my Android Studio Project according to given guide on Altbeacon Sample but the app is not showing the ble device. Can anyone help me what i am doing wrong ?
Following is the code that i am using for scanning PiBeacon.
public class MonitoringActivity extends Activity implements BeaconConsumer {
protected static final String TAG = "MonitoringActivity";
private BeaconManager beaconManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ranging);
beaconManager = BeaconManager.getInstanceForApplication(this);
// To detect proprietary beacons, you must add a line like below corresponding to your beacon
// type. Do a web search for "setBeaconLayout" to get the proper expression.
// beaconManager.getBeaconParsers().add(new BeaconParser().
// setBeaconLayout("m:2-3=beac,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25"));
beaconManager.bind(this);
}
#Override
protected void onDestroy() {
super.onDestroy();
beaconManager.unbind(this);
}
#Override
public void onBeaconServiceConnect() {
beaconManager.setMonitorNotifier(new MonitorNotifier() {
#Override
public void didEnterRegion(Region region) {
Log.i(TAG, "I just saw an beacon for the first time!");
}
#Override
public void didExitRegion(Region region) {
Log.i(TAG, "I no longer see an beacon");
}
#Override
public void didDetermineStateForRegion(int state, Region region) {
Log.i(TAG, "I have just switched from seeing/not seeing beacons: "+state);
}
});
try {
beaconManager.startMonitoringBeaconsInRegion(new Region("myMonitoringUniqueId", null, null, null));
} catch (RemoteException e) { }
}
}
The PiBeacon you reference sends and iBeacon transmission, but by default, the Android Beacon Library only detects open-source AltBeacon transmissions.
It's easy to detect other beacon types, but you need to add a new BeaconParser for the beacon type you are interested in. The instructions are right there in the comments of the code you posted:
To detect proprietary beacons, you must add a line like below corresponding to your beacon type. Do a web search for "setBeaconLayout" to get the proper expression.
Apologies, for the need to do this -- unfortunately intellectual property restrictions mean that we cannot include the expression in the library or post it on public forums like this. Fortunately, it is easy to find with a Google search.
I'm working with the AltBeacon library (2.5.1) to detect beacons.
I setup ranging with an "universal" Region to be able to detect any beacon in range, then do my stuff with it.
The issue is that when I have several beacons in range, the didRangeBeaconsInRegion callback always provides me a Collection of only 1 beacon at a time and this beacon is a random one among all the present beacons... Why can't I get all the beacons in range in my Collection ?
All of this is made from within a Service, I did clean all the other stuff to keep only the relevant parts of the code below -> Hopefully I am doing something wrong here ?
public class MonitorService extends Service implements BeaconConsumer
{
private BeaconManager beaconManager;
#Override
public void onCreate()
{
super.onCreate();
beaconManager = BeaconManager.getInstanceForApplication(this);
beaconManager.getBeaconParsers().add(new BeaconParser().
setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));
beaconManager.setForegroundScanPeriod(5000l);
beaconManager.setBackgroundScanPeriod(5000l);
beaconManager.setForegroundBetweenScanPeriod(1100l);
beaconManager.setBackgroundBetweenScanPeriod(1100l);
setupBeaconManager();
}
private void setupBeaconManager()
{
if (!beaconManager.isBound(this))
beaconManager.bind(this);
}
private void unsetBeaconManager()
{
if (beaconManager.isBound(this))
{
beaconManager.unbind(this);
try
{
beaconManager.stopRangingBeaconsInRegion(new Region("apr", null, null, null));
}
catch (RemoteException e)
{
Log.i(TAG, "RemoteException = "+e.toString());
}
}
}
#Override
public void onBeaconServiceConnect()
{
beaconManager.setRangeNotifier(new RangeNotifier() {
#Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region)
{
Log.i(TAG,"didRangeBeaconsInRegion, number of beacons detected = "+beacons.size());
// HERE IT IS : the size is Always 1, but the beacon (UUID etc. can be different)
}
});
try
{
beaconManager.startRangingBeaconsInRegion(new Region("apr", null, null, null));
}
catch (RemoteException e)
{
Log.i(TAG, "RemoteException = "+e.toString());
}
}
#Override
public void onDestroy()
{
unsetBeaconManager();
super.onDestroy();
}
}
I'm working on Android 5.1.1 with a Nexus 6 (but a Wiko cheap phone gives the same results). The beacons are setup to advertise every 600ms... But even with 100ms it also gives the exact same results...
The code looks OK. A couple of thoughts:
Try using an off the shelf beacon scanner app based on the same library like Locate. Does it detect all of your beacons simultaneously? If not, something may be wrong with the beacons or their configuration.
Do each of your beacons have unique identifiers? The library by default only detects multiple beacons if they have unique identifiers.
I'm trying to detect a Kontakt Beacon with the following BeaconLayout:
setBeaconLayout("m:8-9=0215,i:10-13,i:14-15,i:16-17,i:18-25"));
but I don't seem to be doing it correctly. The advertising packet structure is like this:
Thanks in advance.
Thanks to #davidgyoung comments, I finally could detect my Kontakt beacon with the following code:
public class MainActivity extends Activity implements BeaconConsumer {
protected static final String TAG = "RangingActivity";
BeaconManager beaconManager = BeaconManager.getInstanceForApplication(this);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25"));
beaconManager.bind(this);
}
#Override
public void onBeaconServiceConnect() {
beaconManager.setRangeNotifier(new RangeNotifier() {
#Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
if (beacons.size() > 0) {
Log.d(TAG, "The first beacon I see is about "+beacons.iterator().next().getDistance()+" meters away.");
}
}
});
try {
beaconManager.startRangingBeaconsInRegion(new Region("myRangingUniqueId", null, null, null));
} catch (RemoteException e) { }
}
Please note that I'm using a 2.2 version Kontakt beacon, which is a different version from the layout posted above.
A few issues with your beaconLayout:
The byte offsets in the beaconLayout string start with the manufacturer data (byte 6 in the table you show) so you need to subtract 6 from all of your offsets.
The table shows there are only three identifiers in the beacon, but your beaconLayout string has four. Note the first identifier is 16 bytes long.
If you get it working, please post the correct beaconLayout you used.