How can we get minor and major in monitoring mode when beacon is detected (background) ?
I check https://altbeacon.github.io/android-beacon-library/samples.html but didn't find a solution.
Monitoring APIs do not return the exact identifiers of matched beacons detected. They only return a reference to the Region object that was used to do the monitoring, and if it contains null values for identifiers (wildcards), then you won't know exactly what beacon identifiers were seen.
When you need to know those identifiers, the standard approach is to use the ranging APIs triggered by beaconManager.startRangingBeaconsInRegion(region). The callback for these APIs is didRangeBeaconsInRegion(Region region, Collection<Beacon>)which gives you a list of every beacon matched in the last scan interval.
You can see examples of how to use ranging in the same samples page here: https://altbeacon.github.io/android-beacon-library/samples.html
You can use this sample code.Ranging Example Code.Listed beacons major,minor ex. this
This library looks like a generalized form of beacon detection library. It is not intended only for iBeacons. So you can not get Major and Minor dirctly. But there is a beacon parser class which can be used to accomplished to fulfill this task.Link
Example:
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"));
Related
I've seen a lot of discussions on battery for altbeacon, specially if beacons are inside a region for a long time. This post was actually very clarifying.
I am currently working in a solution that requires a good sensibility (which I define as being a small detection time for a new beacon in a region).
As some beacons may be anonymous (which I define as presenting unexpected MAC addresses but share a same matching byte sequence) to the scanner in this particular solution, I would like to achieve good sensibility to new beacons but also a balanced battery impact to the user.
What concerns me is if a first beacon is found and the region triggers based on the matching sequence, how could I get a notification once another beacon approaches (or leaves) ?
A guess I was going to try was to keep monitoring for a generic matching sequence and once a beacon is found for that general sequence, range it to get its address and them create a particular region for the mac I've taken. The only problem with this approach was how could I prevent the first beacon to keep triggering the generic region?
And just out of curiosity. Is the ScanFilter class related to those hardware filters introduced on android 5?
Thank you,
If you need to quickly find new beacons with the same byte patterns as ones that already exist in the vicinity, you really have no choice but to keep ranging.
In such a situation, there is no distinction between ranging and monitoring in terms of battery consumption. Both will require constant Bluetooth scans and decoding of all beacons in the vicinity. Scan filters (yes, the hardware filters introduced in Android 5,) will not help because you expect the byte patterns to be the same. There is no such thing as a packet "does not match" scan filter that could be used to find only new MAC addresses.
You may need to accept the battery drain of constant scans and just try to limit how long they last, if your use case allows. Short scans of 30 minutes or less might be acceptable.
You could possibly save some battery by writing your own BLE scanning parsing code tailored to this use case. You could first look for unique MAC addresses, and only do further processing and parsing if the MAC address has never been seen before. This will not reduce battery usage from the constant scan, but it would cut down on battery usage from CPU expended on parsing packets. This might save 10-30% depending on the number of beacons in the vicinity.
Bottom line: you are right to be concerned about battery usage with this use case.
My application doesn't use beacons (at least not in the common meaning). The use case is to continuously background scan for BLE peripherals matching a specific format, then connect to those peripherals and transmit/receive data and disconnect (possibly doing this more than once).
The stability and reliability of Bluetooth LE on Android leaves something to be desired, especially if supporting earlier API versions (18+), as I am. AltBeacon seems to be a seasoned library that handles a lot of the weird edge cases and intricacies in Android Bluetooth LE management (at least on the scanning side). I'd like to leverage this library to scan and identify my peripherals and then connect to them on my own. Does anyone know how I might be able to achieve this?
While the Android Beacon Library really is not designed to scan for bluetooth services, there are certain cases where it can be convenient for that purpose. Be forewarned, however, that doing this goes against the grain of its design, and forces you to do a few pretty ugly hacks. If such hacks make your eyes bleed, then read no further! For those who can stand it, here's what you'd need to do:
Set up a beacon parser that will look for a GATT Service UUID. You must match on a few bytes in the service UUID, and the library's matchers are only designed to match a few bytes at a time. So if you have a GATT Service UUID of 00010203-0405-0607-0809-0a0b0c0d0e0f, you should take the first three bytes: 00,01,02 and use them as the matching expression. Because the matching expression has a different endianness, you have to reverse the order of the bytes to be 02,01,00. So you end up with code like this:
BeaconManager beaconManager = org.altbeacon.beacon.BeaconManager.getInstanceForApplication(this);
beaconManager.getBeaconParsers().add(new BeaconParser().
setBeaconLayout("m:0-2=020100,i:0-15l,p:15-15"));
Start ranging based on a region that matches your full GATT Service UUID. (Again, you must replace the UUID with that of your service.):
Region gattServiceRegion = new Region("gattServiceRegion",
Identifier.parse("00010203-0405-0607-0809-0a0b0c0d0e0f"), null, null);
beaconManager.setRangeNotifier(this);
beaconManager.startRangingBeaconsInRegion(region);
Now the library will make a callback to your class' didRangeBeaconsInRegion method each time it sees an advertisement for that GATT Service UUID. So you know it is nearby, and you can get all of the power saving, background launching and other benefits of the library. The problem now is that the library doesn't expose any reference to the raw BluetoothDevice object needed to call connectGatt(...).
So unless you modify the library source code you still have to use the raw scanning APIs once you know the beacon is around just to get this reference. You have to decide if using the Library is worth all this trouble, given that you have to use the raw scanning APIs to get the BluetoothDevice to make a connection, anyway.
I was wondering :
When we enter a shop, using the app shop, we receive for example a notification.
But what if the beacon is down, and it's replaced with another beacon, with a different UUID etc .. ? Are the UUID/Major/Minor value of a beacon not harcoded but in a database on the server ? How it's fetched ?
Thanks you
The UUID of an iBeacon is not related in any way to its MAC address. It is a value that is assigned to the beacon by the beacon owner. Some beacon vendors have a specific UUID or range of UUIDs while others allow any UUID to be used.
If a particular beacon failed then the replacement would likely be configured with the same UUID.
When the app detects a particular beacon it needs to refer to some database, either in the app or on a server, that gives "meaning" to the particular UUID/major/minor combination so it is possible that the database could be updated to reflect the new hardware but this is less likely than simply configuring the replacement hardware with the same values
It is a good practice to not hard code your beacon identifiers in your app. You can build your app so on launch, it contacts a web service to download a list of identifiers to search for. You can build your own or use an off the shelf service like my company's ProximityKit that does exactly this.
Of course, if you are relying on beacon detections to launch your app, your app won't get auto launched to download the new beacon identifiers if the beacon ids change in advance. The user will have to manually do the launch to get the new list.
There are a few ways around this:
Set the identifiers on replaced beacons so they are the same as the old ones.
If you know you cannot set the identifiers, broaden the beacon region filter for auto launch so it matches a wide variety of beacon identifiers. On iOS you can search for all beacons with a shared UUID. On Android, you can search for all beacons regardless of identifiers.
When you initialise Beacon Region then you need to identify at least UUID and it is either hardcoded with in the app or can be placed on the server and should be retrieved from server before calling initialising Beacon Region.
NOTE:You should have a copy of all beacons UUIDs,majors and minors for future purposes
But suppose your Beacon goes out of order then there's a backup plan.
Follow below said steps:
1.Install Estimote-iOS or android app
2.Place the new beacon near to your device and start ranging beacons in estimote app.
3.Then you need to login with your cloud account in your app and configure new beacon(i.e edit your beacon's UUID.)You can even edit major,minor etc
4.Save those settings and your new beacon is configured and ready to use.
Happy Coding :)
We have an iBeacon based ecosystem and want to expand it with Android advertising.
We use the AltBeacon BeaconTransmitter class based on this blog post: http://developer.radiusnetworks.com/2014/11/18/beacon-transmission-with-android-5.html with the beacon layout mentioned in this thread: Is this the correct layout to detect iBeacons with AltBeacon's Android Beacon Library?
We use a Nexus 9 tablet for advertising, our other Android devices can see the advertised beacon, but the iOS devices not.
We create the beacon like this:
mBeaconTransmitter = new BeaconTransmitter(this, new BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));
// Transmit a beacon with Identifiers 2F234454-CF6D-4A0F-ADF2-F4911BA9FFA6 1 2
Beacon beacon = new Beacon.Builder()
.setId1("our uuid")
.setId2("a major id")
.setId3("a minor id")
.setManufacturer(0x0000)
.setTxPower(-59)
.setDataFields(Arrays.asList(new Long[] {0l}))
.build();
What can be the missing part? In the CL's didRangeBeacons method we can't see this beacon.
The Android Beacon Library's new BeaconTransmitter class requires that the new BeaconParser.setBeaconLayout() expression be exactly right for the beacon type you wish to transmit.
Two things about the code look suspicious:
The code calls setDataFields() on the beacon even though no data fields are defined in the beacon layout expression (with a d: prefix). This should probably cause an exception, but if it does not, it could be screwing up the transmission. I would remove this.
I am not sure if a manufacturer code of 0x0000 is valid. If (1) does not solve the problem, try different manufacturer codes to find one that works with iOS.
Just to verify there is no problem with the Nexus 9 hardware, try running the free QuickBeacon app in the Google Play store. It uses the exact same APIs to transmit, so if it works you should be able to make your code work, too.
I'm currently working on an app on Android which detects iBeacons using the API provided by Kontakt, to execute actions configured online in the Kontakt CMS.
However, to detect beacons, I am using the Radius Networks BLE libraries. I was unable to extract the UUID from the beacons, is this feature only available in the Pro Library? If it is available for the Open Source Library, how do I detect beacons with their UUID?
Region region = new Region("myRangingUniqueId", uUID, null, null);
Should be able to range for that to get a list of beacons matching that uuid from didRangeBeaconsInRegion callback.
Unless you just want to range for all beacons, then you can leave the proxUuid field null (wildcard) and then iterate through and get the proxIds with
iBeacons.iterator().next().getProximity()
Yes, you can do this with the open source Android iBeacon Library.
First, make sure your beacons are transmitting properly by verifying you can detect therm with the free iBeacon Locate app.
If this works, take a look at the "Ranging Example Code" here, which shows how to read the beacon ids.
EDIT: This library has been replaced by one with a the Android Beacon Library 2.0. The Ranging example is now available here.