IOS: iBeacon scanning frequency when phone is locked? - ios

If an iBeacon starts emitting (100ms), how long should it takes before a locked iPhone detects it? Let's say the iPhone is very close to the emitting iBeacon but my app is not even running in the background.
In other words, what is the LBE scanning frequency when an iPhone is locked?

We have done a lot of research on this subject at Radius Networks. The answers are complicated, but the executive summary is that their are two tiers of detection:
Hardware Accelerated: The first beacon apps to register the first 30 beacon regions on the phone get hardware accelerated detection. Thisey get background detection within 5 seconds about 90% of the time.
Software Scanned: Subsequently registered beacon regions get detections as software allows. If no other apps are ranging, this is on a fixed 15 minute interval. Statistics say that the average detection time would be 7.5 minutes for these regions. The maximum time is 15 minutes.
Unfortunately, there is no known way to tell which tier your app will get. Plan accordingly.
Read more here:
http://developer.radiusnetworks.com/2015/04/21/max-beacon-regions-ios.html
http://developer.radiusnetworks.com/2014/03/12/ios7-1-background-detection-times.html

The documentation doesn't seem to be really specific about the scanning times, and I feel like most of the information one can find is going to be anecdotal.
From my personal research and experience, beacon scanning when the app is backgrounded or inactive is variable on the iPhone's battery level and various other factors. For the most part, in most cases, I've determined that region detection should occur within a few seconds.
With that said, I've noticed that it happens a little faster when the phone is in use, taken out of the pocket, etc. This could be due to the fact that as the phone is moving, scanning is increased to bring the user up to speed and prepare apps for use.

Related

Minimise battery consumption on Beacon Ranging in iOS while using iBeacon

I'm working on a use case that needs continuous callbacks while scanning the beacons.
I've thought of 2 approaches but they both have issues.
Monitoring: Monitoring only gives entry and exit callbacks. There's a limitation of listening to only 20 beacons. Also is there a range that i can define to get entry and exit callbacks? Like say if a an advertising beacon comes in range of 2 meters i get an entry callback and if the device moves out of that range i get an exit callback.
Ranging: Ranging gives continuous callbacks along with a set of other parameters like rssi to calculate distance. The big issue when it comes to ranging though is that it consumes insane amount of battery compared to monitoring. What should be an approach for getting continuous callbacks while optimising battery consumption?
I've tried both the approaches and reached to a dead-end. Hence it may seem like a theoretical question yet any insights to solve the use-case in some manner.
It is not possible to set any kind of rssi or distance filter when using iOS CoreLocation beacon monitoring APIs. Ranging is the only alternative when working with iBeacon.
While battery drain of constant BLE scanning is an issue, you an mitigate this by scanning on a lower duty cycle as needed to meet your requirements. For example, you can scan on a 20% duty cycle (and use 20% as much battery as constant ranging) by ranging for 12 seconds every minute. You can adjust this duty cycle as needed to balance your goals between battery savings and responsiveness. I have worked on projects where I change this duty cycle depending on app state, so the app can be more responsive to beacons when it is important and save battery when responsiveness is less important.
In order to be able to do this at all, you must unlock the ability to have iOS let your app run in the background for an unlimited time period as described in my blog post here:
Add the location background mode to Info.plist
Obtain "always" location permission from the user. It is not sufficient to get "when in use" permission.
Start a background task as described here: http://www.davidgyoungtech.com/2014/11/13/extending-background-ranging-on-ios
Request 3km location updates from CoreLocation. This will keep the app running in the background without extra battery drain from GPS, as 3km accuracy only uses the cell radio You don't need to do anything with these results. You just need to request them to keep the app alive.
Once you do the above, you can call locationManager.startRangingBeacons(...) and locationManager.stopRangingBeacons(...) on a timer to implement whatever duty cycle you want.

iBeacon Transmission seems unstable, Altbeacon android Kotlin

When I tried to create iBeacon and then detect the beacon for some region range notifier does't notify the bacon for very small interval of time after again it starts appearing but there is drop for second and beacon gets disappear and again is start to appear.
I expect when an beacon is emitting then Range notifier should always return the beacon but sometimes it goes to 0 count and then again it returns the beacon.
**val beacon = Beacon.Builder()
.setId1("f7826da6-4fa2-4e98-8024-bc5b71e0893e")
.setId2("1")
.setId3("2")
.setManufacturer(0x004c)
.setTxPower("-59")
.build()**
**beaconTransmitter = BeaconTransmitter (this, BeaconParser()
.setBeaconLayout ("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24");
beaconTransmitter?.startAdvertising(beacon)
mBeaconManager = BeaconManager.getInstanceForApplication(applicationContext)
mBeaconManager?.beaconParsers?.add(BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"))**
**private val mRangeNotifier = RangeNotifier { beacons, region ->
//Here I receive zero beacon some time, mostly it works but form very small interval of time beacon count is zero
}**
There should be proper detection of beacon so no inconsistency occurs, at least I could always track the beacons.
I have tested it on -
One plus 5 with Android version 9
One plus 6 Plus with Android version 9
Poco F1 with Android version 8
Library version - 2.16.4
There are lots of variables here where there could be a problem:
The code shown (or supporting code not shown in the question.)
Hardware issues with the transmitting phone.
Hardware issues with the receiving phone.
Because you are working with three different phones, the combinations of possible sources of trouble grow with the combinations of phones.
In order to track this down, you must simplify your test cases:
Use a reference beacon transmitter for your tests that is most reliable. Choose a hardware beacon (best) or laptop-based beacon transmitter program (better) if you have one available. If you have no other choice, pick one of the phones to be the transmitter, and choose the one you suspect is most reliable.
Use an off-the-shelf beacon detector program based on this same library such as Beacon Scope, and test detections of the beacon. Using an off the shelf program will eliminate any coding errors in your detection software.
Test the off the shelf detection on each of your phones. This will tell you which, if any, have hardware trouble if they fail to detect reliably.
Once you have a reliable transmitter and know which phones are reliable detectors, go back to your program and work to make it as reliable as what you see with Beacon Scope using the most reliable transmitter.

Caveats for background iBeacon Region Ranging

Apple explicitly discourages background iBeacon Ranging:
To promote consistent results in your app, use beacon ranging only while your app is in the foreground.
If your app is in the foreground, it is likely that the device is in the user’s hand and that the device’s view to the target beacon has fewer obstructions.
Running in the foreground also promotes better battery life by processing incoming beacon signals only while the user is actively using the device.
Should I choose to go naughty and do some ranging in the background (after entering a beacon range when monitoring), what consequences should I expect? (except for the famous 10-seconds running window before being put to sleep again?
In most cases, there is no reason to worry about battery drain from casual background ranging.
I've read that statement before, but I don't think it makes any sense, and suspect it was written before the CoreLocation iBeacon design was complete. (The statement has been there since the iOS 7 beta.)
Apple iOS generally enforces that you can only range in the background for 10 seconds at a time, typically triggered by a CLBeaconRegion monitoring entry/exit event. Unless you app is in an extreme situation where it is seeing beacon regions enter and exit all the time, 10 seconds of background bluetooth scanning just can't use that much battery.
Of course, there are techniques where you could range more often, such as requesting location background mode for constant ranging, or requesting an extra 3 minutes of ranging time as described in my blog post here. If you use one of these techniques, you should probably test the impact of your app on battery. But I certainly wouldn't describe doing these things as being "naughty" as long as you do so responsibly.

How long does it take to detect an iBeacon while region monitoring?

Take this scenario: user has an iPhone in the pocket passing by an iBeacon. Her phone is region monitoring for it. How much time is needed in real world to from entering the region to the moment app is woken up?
I have found an excellent article on the subject by David G. Young (http://developer.radiusnetworks.com/2013/11/13/ibeacon-monitoring-in-the-background-and-foreground.html) but I can't believe it can really take up to 15 minutes.
That would mean that all iBeacon home automation scenarios are simply unusable because you won't neither wait 15 mitutes in dark room for lights to switch on neither you would switch on the lights by actively using an app. Door opening and locking is another situation where iBeacon would be unusable (and NFC would work much better here). Or am I missing something?
I have an app that ranges for an iBeacons. It first grabs a list of couple proximityUUIDs and registers them as monitored regions.
When the device enters that region, it takes just 1 to several seconds (iPhone 5S) to post me a local notification on didEnterRegion: event.
When the app is in front, it starts ranging the beacon immediately in current region (if any) and updates happen in about one-second intervals.
When the app is in background, ranging is not enabled, otherwise it would immediately report that the beacon is gone (if you leave its range).
HOWEVER, It can really take up to 15 minutes (I've experienced this) for the device to post the didExitRegion: when in background in the worst case, when there is just significant location monitoring enabled combined with bad or no network. Otherwise it happens until about a minute.
Sorry, this didn't fit into a comment.

How to limit the advertising range of a beacon?

Is it possible to limit the ranging of the beacon, so that only devices within a certain close range(or proximity) can identify and connect to the beacon? Lets say for example the devices outside 0.5 meter zone shouldn't be able to see or connect to the beacon. I am using a iOS device as a beacon. In the Apple's CoreLocation API, there is a method called peripheralDataWithMeasuredPower in the CLBeaconRegion class which says:
peripheralDataWithMeasuredPower:
Retrieves data that can be used to advertise the current device as a beacon.
(NSMutableDictionary *)peripheralDataWithMeasuredPower:(NSNumber *)measuredPower
Parameters:
measuredPower:
The received signal strength indicator (RSSI) value (measured in decibels) for the device. This value represents the measured strength of the beacon from one meter away and is used during ranging. Specify nil to use the default value for the device.
Can this be used to limit the range of beacon? If yes, I am unable to understand how to decide the value to set for measurePower parameter? What are they trying to say by ...value represents the measured strength of the beacon from one meter away..?
Please forgive if this is a very basic question. I've recently started iOS development and will appreciate your help. Thanks.
Unfortunately, there is no easy way to adjust the range of an iBeacon without special hardware.
The power field that you mention is simply a calibration value transmitted by an iBeacon. It doesn't affect the actual physical radio range of the iBeacon. If the transmitter can be seen by an iPhone 50 meters away, altering the power field value will not change this at all. The only thing it does is change is the calibration constant which is an input to the distance estimation algorithm (used for the accuracy and proximity fields) inside the iOS software. Altering the power field will affect the estimated distance returned by the API, but it won't change the actual distance at which the iBeacon is first detected.
Altering the transmit power of a standard bluetooth iBeacon is practically impossible. In theory you can use metal shielding to construct a "faraday cage" around the transmitter to mute its power, but my experience is that it isn't very effective and it is highly susceptible to tiny imperfections in the shielding. If you want to change the transmit power you have to have somebody build you custom hardware.
The software alternative is to use the ranging API to track an iBeacon while it is visible, and only perform an action when the estimated distance is close enough, say 0.5 meters as you suggest. This works great -- only in the foreground.
If you require actually waking up your app in the background at a close range, this won't work. The best you can do is have the monitoring API wake up your app when the iBeacon is first detected, and then send a notification to the user and start ranging. If the user elects to bring the app to the foreground (at 50 meters) you can keep monitoring and then perform your desired action at 0.5 meters. If the user does not elect to bring the app to the foreground, iOS will only give you about 5 seconds of time to continue ranging before it suspends your app. It is very unlikely that the distance will change from 50 meters to 0.5 meters in this time.
With most BLE chips I've investigated, there are usually at least four settings for transmission power level that can be used to limit the advertising range.
The Texas Instruments CC2541 (as used in their SensorTag development device) and CC2540 have +4, 0, -6, and -23 as their power level options. However, changing that in the SensorTag does require a recompile of the firmware. As-is, the provided firmware mentions the power level in only one place, but that is just a value that is broadcasted to inform any central listener how loud the beacon is—so that the central device can better calculate an estimated range based on received signal strength (RSSI). An additional line must be added to the firmware to actually change the transmission power. For example:
HCI_EXT_SetTxPowerCmd( HCI_EXT_TX_POWER_0_DBM );
Based on this, there should be two places on an iOS device where you can set the power level: one that just informs the listeners what the level is, and one where the BLE chip's true transmission power is actually changed. However, expect these values to be restricted to only a few enumerated choices which may or may not meet your real-world range needs.
(The SensorTag's -23 setting would probably do well for a 0.5 meter detection range. But if you want the SensorTag to always be advertising, it will require an additional firmware change.)
Have you looked to see if the proximity property was helpful? From the apple docs:
CLProximity
Constants that reflect the relative distance to a beacon.
typedef {
CLProximityUnknown,
CLProximityImmediate,
CLProximityNear,
CLProximityFar
} CLProximity;
I would also experiment trying to combine the the proximity with accuracy and rssi.
It's gonna vary from beacon to beacon. If you use beacons from Radius Networks, they have a transmit power setting that lets you essentially limit the ability of the beacon radio to broadcast to long ranges. I don't know if other brands have it, but most do not from what I've seen.

Resources