Android iBeacon Library fromScanData returning null always - android

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.

Related

Capturing data packets from beacon using Altbeacon

I've a specific beacon that transmits data packets. I can see that Altbeacon library recognises this beacon (from minorId) and I can see that packetCount is 1, but what I cannot see is packet itself (from Beacon object). How can I do that? How can I get Beacon advertisement bytes - I know I can use setDebug(true) to see them in console, but is it possible to retrieve it in code programatically? How? Thanks in advance.
Beacon sends three things which you can capture using functions like beacon.getId1() which is UUID, beacon.getId2() which is major and getId3() which is minor.

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 setBluetoothAddress and setBluetoothName

I'm attempting to transmit as a beacon an Android phone using the altbeacon library as described here. I am trying to set some parameters using the following methods:
setServiceUuid(0xfeaa)
setBluetoothAddress("31:14:15:92:65:35")
setBluetoothName("MyBeacon")
When the beacon is interpreted on another Android device in the RangeNotifier listener method, didRangeBeaconsInRegion, the beacon doesn't have these parameters set. (eg. getServiceUuid is -1 and the BT address and name are each null).
I'm using the following beacon layout in the parser for the transmitting application and in the scanning application:
m:2-3=beac,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25
I don't know what this means though; I wonder if I need to change it.
Anyone have an idea how to make the bluetooth address, name etc. be accessible in the beacon that is scanned on the receiving device?
Some fields in the Beacon class are only used when detecting beacons and do not affect transmissions. You have found three of these exact fields. Here is an explanation of each and why they work this way:
BluetoothAddress: this is a fixed six byte unique address built into the Bluetooth chip on your phone. When sending packets (beacon advertisements or otherwise), the chip always uses the same address. You cannot change it. This is by just the way Bluetooth works.
BluetoothName: this is the friendly name of your phone visible to other Bluetooth scanners. Changing this name affects not just beacon transmissions but all Bluetooth operations on the phone. For this reason, the library's BeaconTransmitter does not change this name. You can do so youself, however, by calling the setName method on Android's BluetoothAdapter class. See here.
ServiceUUID: This field applies only to certain beacon formats such as Eddystone, which are based on 16-bit GATT Service UUIDs. For other beacon formats (AltBeacon, iBeacon), this value is -1 as you have seen. The ServiceUUID is actually defined in the BeaconParser layout expression. In the Beacon class you can read it, but writing to it has no effect. You generally do not need to worry about this field, and certainly not for the AltBeacon layout shown in the question, because it is not used for that format.

Use Find Me Profile in Android 4.3

I a trying to understand and modify the BLE sample von Android.com, now I can discover my sample BLE Device (HTC Fetch) and now I want to understand all that GATT and BLE stuff.
What are Characteristics and what are Profile and what are Serivces and what do they mean in the Bluetooth Low Energy World? I used HTC Dev and found a Service and a Characteristics UUID.
https://www.htcdev.com/devcenter/opensense-sdk/bluetooth-smart/htc-fetch/
But I guess what I need is the Find Me Profile, cause for the first steps I only want to get the Find Me react to a Button click.
https://developer.bluetooth.org/gatt/profiles/Pages/ProfileViewer.aspx?u=org.bluetooth.profile.find_me.xml
How to implement this in my App?
When I understand everything I try Power and Proximity (reading RSSI and compare with defined range).
Can some one help me understanding Bluetooth LE?
Here's a related post
How to use the profile of PROXIMITY PROFILE,IMMEDIATE ALERT SERVICE and Find Me Profile in android 4.3 BLE?
Basically you can approximate a proximity level using tx+power - rssi or distance roughly with
d = (rssi-A)/-20 (where A = rssi at one meter) or simply use rssi mapping out ranges to display You could also initially base it on just the connection range and skip rssi.
As for the FindMe, simply write the low or high alert values to make it sound when you press a button in your app. For pressing a button on the device use the UUIDs shown in the documentation.
sample code for that device is forthcoming

RSSI from Bluetooth Low Energy (BLE) Tags?

I'm writing an app (on android) to read RSSI from bluetooth devices, for location recognition using rssi fingerprinting. I have working code for reading RSSI from non-paired and discoverable bluetooth devices that are not BT4.0/BLE. I would like to know if I get some BLE-based tags (such as stick-n-find) would I be able to read their RSSI only by putting myself (my android phone to be precise), into bt-discovery mode.
In BT Low Energy the roles are switched.
The Stick-n-find would be Advertising it's service(s) Name or other information. When you receive that Advertisement from your iOS APP you will get an RSSI value with that Advertisement.
So just do something like:
#property (strong, nonatomic) CBCentralManager *CM;
#define SERVICE_ID_STR "4d1dc300-424d-13e2-a661-0002a55dc51b"
self.CM = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
NSDictionary *scanOptions = [NSDictionary dictionaryWithObject:[NSNumber
numberWithBool:NO] forKey:CBCentralManagerScanOptionAllowDuplicatesKey];
CBUUID *peripheralUUID = [CBUUID UUIDWithString:#SERVICE_ID_STR];
[self.CM scanForPeripheralsWithServices:[NSArray arrayWithObject:myUUID]
options:scanOptions];
then when it hears the Advertisement package from a Peripheral you will get
- (void)centralManager:(CBCentralManager *)central
didDiscoverPeripheral:(CBPeripheral *)peripheral
advertisementData:(NSDictionary *)advertisementData
RSSI:(NSNumber *)RSSI {
where you get the RSSI.
If you only want a callback to didDiscoverPeripheral for the FIRST time the peripheral is heard then don't use the ScanOptions
[self.CM scanForPeripheralsWithServices:[NSArray arrayWithObject:myUUID] options:nil];
From what I gather, some Android phone manufacturers may include BLE support, but it is not currently supported by Android directly (as of 4.2 Jellybean). See Issue 33371 for more info.
It looks like BLE may be coming in the next Android version as hinted in this Google Groups discussion.

Categories

Resources