iOS devices can't see Nexus 9 advertised AltBeacon beacon - android

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.

Related

Altbeacon 2.16.1 can't scan beacons with specific beacon type code

I am building an Android app that scans two types of beacon using the android-beacon-library:
iBeacon type (0x4c000215)
custom beacon which beacon type code is 0x4106
I know there was an issue that fixed broken Samsung screen off scans https://github.com/AltBeacon/android-beacon-library/pull/798.
That fix was implemented into the 2.15.3 release.
Since then, during every scan with a samsung device >= Android 8.0, I don't see any of my custom beacon but I do receive other beacon types like iBeacon. So I am still using the 2.15.2 release.
Here is my custom beacon layout:
"m:0-1=4106,i:2-3,i:4-4,i:5-6,i:7-8,i:9-10,i:11-11,i:12-12,i:13-13,i:14-14,i:15-15,i:16-16,i:17-17,i:18-23,p:24-24"
I checked the code from the lib and I can see a filter that applies for samsung devices only:
if (Build.MANUFACTURER.equalsIgnoreCase("samsung")) {
// On the Samsung Galaxy Note 8.1, scans are blocked with screen off when the
// scan filter is empty (wildcard). We do a more detailed filter on Samsung only
// because it might block detections of AltBeacon packets with non-standard
// manufacturer codes. See #769 for details.
filters = new ScanFilterUtils().createScanFiltersForBeaconParsers(
mBeaconManager.getBeaconParsers());
}
If I remove this code, everything works as I expect.
Is there something I have to do so I don't need to edit the library?
Thanks.
The library uses both the BLE manufacturer ID and the beacon type code to match BLE filters when the app is in the background. For this to work, you must set these up exactly right, or the filters will not match.
Two issues here:
Your beacon type code should not include the BLE manufacturer ID. Instead of 0x4c000215 use 0x0215 (Note: 0x4c00 is the Apple BLE manufacturer ID, and will be applied separately.) If using a beacon layout string with this, you must adjust the byte offsets to account for this, so your layout starts with m:2-3=0215
For any beacon layout that will be matched with these filters, you must set the hardware assist manufacturer identifiers. By default, the library includes 0x0118 (Radius Networks for AltBeacon) and 0x0215 (Apple for iBeacon) for all other manufacturer beacon types. For any custom beacon that uses yet another manufacturer code (see list here: https://www.bluetooth.com/specifications/assigned-numbers/company-identifiers) you must add it like this (example shown for hardware manufacturer id 0x1234):
beaconParser.setHardwareAssistManufacturerCodes(new int[]{0x1234});
Important tip: Mobile devices have a limited number of bluetooth hardware filter slots. You can help ensure you do not run out of them by:
Only register as many beacon layouts as you need. If not using the default AltBeacon layout, call beaconManager.getBeaconParsers().clear(); to remove it.
Only register the exact hardware manufacturer codes you need with each BeaconParser. If you register more than one you will use more than one filter slot.
The above APIs were designed before this Samsung restriction came into place making this a more serious issue. I am open to other ideas on how to make this API more intuitive so other folks don't run into the same problem as you did.

AltBeacon Minor & Major

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"));

Using AltBeacon as a Wrapper For BLE Scanning/Connections

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.

Detecting iBeacons UUID using Radius Networks Android Beacon Library

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.

Android iBeacon Library fromScanData returning null always

I have been trying to write an application to detect iBeacons. (I set up my iPhone 5 as iBeacon)
I slightly changed the fromScanData method to return only proximity UUID String. I have no idea how the pattern detection works. It always Logs "This is not an iBeacon advertisement".
I am not using the whole IBeacon class. I am using the method alone. I am calling it from my
onLeScan and passing the byte array scanRecord, rssi value and the BluetoothDevice object.
Once I have my proximity UUID for each ble device, I can filter the ones I want.
Please help. Thanks in advance.
The Log
04-17 14:44:29.828: D/BLEScan(28549): This is not an iBeacon advertisment (no 0215 seen in bytes 4-7).The bytes I see are :02011a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
The debug line says it all. Those bytes do not indicate a valid iBeacon advertisement. Are you sure your iPhone transmitter is really working properly? Can you detect the iBeacon using a different tool like the Android iBeacon Locate app?
I don't know how you set up the transmitter but you might also try Locate for iBeacon iOS app or EZ Beacon iOS app, which are known to transmit properly formed iBeacon advertisements that work with this code. The same Android code is inside the iBeacon Locate app.
Finally, make sure your iPhone transmitter is in the foreground. iOS devices cannot transmit as iBeacons in the background.

Categories

Resources