Scanning for altbeacons with specific manufacturer code - android

I am attempting to intermittently scan for nearby beacons and store off every received beacon with a particular manufacturer code. How do I use the altbeacon Library to start and stop scanning for altbeacons with a specific manufacturer code and store off every received beacon during each scan? I would like for the scanner to scan for 20 seconds every 5 minutes after the activity has been created.
#davidgyoung

For the manufacturer code 268 (hex 0x0112), you can match this with the following BeaconParser setup code:
beaconManager.getBeaconParsers().clear();
beaconManager.getBeaconParsers().add(new BeaconParser().setLayout("m:0-3=1201beac,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25"));
Note that in the layout string, the two hex bytes of the manufacturer code are put as the first part of the "matching" m expression m:0-3=1201beac. They are in reverse "little endian" order because this is how they appear in the packet. So 0x0112 becomes m:0-3=1201. Similarly if you were using radius networks 0x0118 company code, you would use m:0-3=1801.
The regular ranging APIs will return you a list of all beacons that match this. To scan for 20 seconds out of every 5 minutes, simply use:
beaconManager.setForegroundScanPeriod(20000l); // 20,000 ms
beaconManager.setForegroundBetweenScanPeriod(280000l);// 280,000 ms + 20,000 ms = 5 minutes

Related

altbeacon detection of beacon RSSI values continuously at 10Hz

I created an android (java) application that uses the altbeacon library (github page) to detect beacons via the Bluetooth module.
The Beacons are configured with Eddystone UID, protocol with an advertising interval of 100ms and transmit power level of strong (10dBm).
What I would like to be able to do is to detect the RSSI value of the beacons with a frequency of 10Hz (i.e. 100ms).
I've already prepared a service that implements the altbeacon library, the relevant part are showed below:
mBeaconManager = BeaconManager.getInstanceForApplication(this);
beaconRegion = new Region("beacon_region", null, null, null);
// use Eddystone protocol
mBeaconManager.getBeaconParsers().add(new BeaconParser().
setBeaconLayout(BeaconParser.EDDYSTONE_UID_LAYOUT));
mBeaconManager.setAndroidLScanningDisabled(true);
mBeaconManager.setForegroundScanPeriod(100l); // scan frequency
mBeaconManager.setForegroundBetweenScanPeriod(0);
and the callback didRangeBeaconsInRegion from which I see the beacons and get the RSSI value is this:
#Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
Log.i(BeaconDataCollectorService.class.getSimpleName(), String.format("Found %s beacons in range", beacons.size()));
}
What's my problem?
Running the app, I notice that within didRangeBeaconsInRegion, I often don't see all the beacons.
I ran the data collection for a few seconds, creating a csv format of the data obtained, where you can see that I often have 0s (indicating that the beacon was not detected); I put the sharing of this csv on pastebin (https://pastebin.com/zkUZC5R4)
How can I improve the scan frequency by always being able to detect all the beacons?
altbeacon version used:
implementation 'org.altbeacon:android-beacon-library:2.16.3'
Android version: 9
Thanks
Unfortunately, the library is not designed to do this, as the ranging APIs are modeled after iOS equivalents which give aggregate detections at fixed intervals as opposed to access to individual packets when they arrive.
The main reason you often get 0 beacons detected with such a short scan period is because the scan is turned on and off every 100ms, and it takes 10ms or so to start and stop. This gives a good probability of missing the detection.
Here's the good news: If the library ever detects two beacon packets in the same scan period then it will stop turning the scan off and your detection rate will improve. But getting it to detect two beacons in 100ms is nearly impossible of your beacon advertises at a nominal 10Hz.
One thing you might try is to start by setting the scan period to 1 second. After you have detected a finite number of your beacons for 10 secs or so, there is a very good chance you will have detected two beacons in one scan cycle and then you can switch to a scan period of 100ms and get a higher detection rate.
You will never get a 100% detection rate for two reasons:
Not all beacon packets transmitted are received due to collisions and radio noise. At close range 80-90% is typical.
"BLE advertisers do not advertise at regular intervals. They randomize when their packets are sent to avoid collisions. A nominal 10Hz transmitter might have anywhere between 70ms and 140ms between individual packets, so for fixed scan cycles of 100ms sometimes there will be 0, 1 or 2 Packers eligible to be received.
If you really need to get callbacks on every detection, you might try setting up a NonBeaconBleScanCallback in the BeaconManager, then calling BeaconManager.clearBeaconParsers(). This will cause all beacons detections to be sent to that callback immediately when detected. You will then have to construct a new BeaconParser for use inside that callback to decode the beacon from the raw packet. Use beaconParser.parse(...)

Different interval time between BLE device advertising and the callback from startScan of android phone

I use android phone to detect a beacon using startScan method, the interval time of beacon adversing is 800ms, but I got the beacon data from callback of startScan every 3~10 seconds. My expectation is I can get the data every 1 second.
Below is my codes. So is there any other ways to get my expectation. Or someone can explain why the interval time is not the same as the adversing time ?
ScanSettings.Builder builder = new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY);
// scan filters has been set the right value.
bluetoothLeScanner.startScan(scanFilters, builder.build(), scanCallback);
Nothing about the code shown is a problem. I can confirm your expectation is met with equivalent code in other apps on other devices. This suggests a problem with :
Your BLE device not advertising as often as you expect
Your Android phone (possible but unlikely)
Some other aspect of your code that you did not show in your question.
Is you BLE device a beacon? If so, I suggest:
Install BeaconScope on the same phone, scan for your beacon, then check the PPS rating (Packets Per Second -- scan for at least 30 seconds until the measurement stabilizes). If you see a value of 0.1-0.3 then the problem is NOT with your code and must be (1) or (2). If you see a much higher PPS value, the problem is with some other aspect of your code not shown.
Use a second Android phone with BeaconScope as a transmitter and transmit a beacon at the 10 Hz default rate. Does your app get a packet every 100-200ms? If so, you have confirmed the problem is with your BLE device not transmitting as much as you expect.
If your BLE device is not a beacon you can at least perform the second test.
It's recommended to use 'SCAN_MODE_LOW_LATENCY' mode only hen the application is running in the foreground.
Incase you are in background, you can run a sticky foreground service and set a periodic frequency of 1 sec for your service.
Also scanning Ble for every 1 sec might be extremely heavy for the app.

Is there a way to increase BLE advertisement frequency in Android?

I have an Android device broadcasting a BLE advertisement using the following commands of AltBeacon library:
ADVERTISE_MODE_LOW_LATENCY approx 1 Hz
ADVERTISE_MODE_BALANCED approx 3 Hz
ADVERTISE_MODE_LOW_POWER approx 10 Hz
I would like to increase this frequency more than 10 times per second. Is there a way to increase advertising frequency in Android? Or it is unchangeable?
You can reach it with stopping and starting advertisement with code like this:
while (true) {
beaconTransmitter.stopAdvertising()
beaconTransmitter.startAdvertising(beacon, object : AdvertiseCallback() }
The different options you have shown that work with the Android Beacon Library's BeaconTransmitter class are built-in to Android. Unfortunately there are no other higher frequencies of transmission offered by Android APIs.
However, on many newer devices you may start more than one advertiser at a time. If you have a device like this (Pixel, Nexus, Galaxy, Nokia) you can simply start more than one BeaconTransmitter instance at a time, each set to advertise 10Hz. If you start 10, you effectively get advertising at 100Hz.

Beacon scanner does not scan one beacon signal for more than 10 seconds

Hello I am poor at English.
I use Android Beacon Library
implementation 'org.altbeacon:android-beacon-library:2.15.2'
My Android application gradle imformation
compileSdkVersion 28
minSdkVersion 21
targetSdkVersion 28
My Beacon manager information
beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));
beaconManager.setForegroundScanPeriod(1100L);
beaconManager.setBackgroundScanPeriod(1100L);
beaconManager.setForegroundBetweenScanPeriod(0);
beaconManager.setBackgroundBetweenScanPeriod(0);
beaconManager.enableForegroundServiceScanning(notificationcompatBuilder_Scannging.build(),456);
beaconManager.setEnableScheduledScanJobs(false);
BeaconManager.setDebug(true);
regionBootstrap = new RegionBootstrap(this, myBeaconRegion);
Error
I want to develop all day beacon scanner application.
So I use regionBootstrap to scan in background.
It looked like it was working.
However time passed and Exit Event suddenly occurred and Enter Event occurred shortly after.
I think scan does not work for a few seconds and I have conducted a test on this.
Error Test 1
one smartphone , two beacons
Error1
One beacon signal is not detected for more than 10 seconds while another beacon signal is detected.
So I think scan work well and it is a problem of beacon.
Error Test 2
two smartphone , two beacons
smartphone 1
enter image description here
smartphone 2
enter image description here
In smartphone 1 Logcat, Also One beacon signal is not detected for more than 10 seconds while another beacon signal is detected.
In smartphone 2 Logcat, Unscanned beacon is being scanned at the same time.
So beacon does not problem and I can't find reason.
Error Test 3
Added test
two smart phone
My beacon transmit the signal about once every three seconds.
In smart phone 1, download the other beacon application which has beacon signal transmit and transmit at 1Hz.
In smart phone 2, by using my application, watch the signal.
enter image description here
The beacon signal of smart phone 1 increase markedly, but the same problem arose.
Does anyone know about this matter?
I want a help...
Please
I suspect that the beacons you are using to test are not transmitting frequently enough. Manufacturers often reduce the transmission rate to save battery. When the transmission rate gets below 1Hz, this can cause problems, because not 100% of beacon packets transmitted are received by any phone. Radio noise often causes packets to be missed. If one device misses a few packets in a row (it happens sometimes) it causes a region exit event.
The solution is to increase the frequency at which the beacons transmit. With some manufacturers this is configurable. With others, it is not. If it is not configurable, you may need to buy different beacons
You can test if this is the problem by using an Android beacon simulator app on one of the devices. Try my BeaconScope app, which will advertise at 10Hz by default.
This library return result only when a specific event is triggered, not for all beacon scanned.. if you need this I suggest you to use the standart android standard beacon library, if you want to know more about this and how to implements comment this post and I'll edit it with the implementation

Beacon Library - Transmitter

I created a transmitter app with this Error code 2 in beacon transmitter for Android Beacon library code and able to transmit as iBeacon.
Problem 1: The app no longer able to transmit if i killed the app from recents(Should i call this from foreground service? Any in-built API from altbeacons library?)
Problem 2: I need to send a 10 character String to scanner after connection established, but setDataFields() only allowing for 6 digits.
It is a bit tricky to keep an Android app running in the background, which what you need to do to keep a transmitter going.
The Android Beacon Library does this automatically for scanning purposes, so you could use the library's reference app as a starting point and put the transmission start in the onCreate method of the Application class.
This would keep the transmitter going pretty much forever on Android 5-7. On Android 8 you are limited to running in the background for about 5 minutes out of every 15 unless you build a foreground service.
EDIT
If you wish to advertise several bytes of data, your best bet is to encode it in the 16 byte ID1 (ProximityUUID) field. You can reserve the first few bytes for determining if the beacon is yours, then use the last 10 bytes or so to encode your data. On the receiver side you can use identifier.getBytes() to convert your first identifier to a byte array so you can access data elements inside of it.

Categories

Resources