Android BLE proximity notifications

I am working on developing an application that interacts with BLE devices. Everything works fine, I can scan, connect and consume services.

I read all the documents and I don’t see anything that gives the developer the ability to listen to BLE devices. Basically, I would like to start the broadcast receiver when the devices are in the range of the BLE device.

I know that I could constantly check this, but the battery usage is too much, and I would like it to be called even when my application is not in use.

Is this feature unsupported or am I missing a section of the docs that discuss this?

+7
java android android-bluetooth bluetooth-lowenergy
source share
4 answers

I recently made a project, and from what I read in your question, it has some similarities with what I did.

I know that I could constantly check this, but the battery usage is too much, and I would like it to be called even when my application is not in use.

Regarding the battery problem, when Bluetooth consumes a lot of power all the time, but at the same time you cannot detect BLE without turning on Bluetooth.

What I did is two experiments, and both of them are useful, but different, and I can’t say which one is better, but you need to test it so that it meets your requirement.

  • After starting Thread, which turns on Bluetooth and listens to iBeacon on and off (with sleep time), while programmatically. This can be done in many ways.

  • Using a package called Altbeacon, there are many useful functions, one of these functions is to automatically save the battery with an example code :

    public class MyApplication extends Application implements BootstrapNotifier { private BackgroundPowerSaver backgroundPowerSaver; public void onCreate() { super.onCreate(); // Simply constructing this class and holding a reference to it // in your custom Application class // enables auto battery saving of about 60% backgroundPowerSaver = new BackgroundPowerSaver(this); } } 

We need a broadcast event that wakes up our application when a BLE device with a specific Service-UUID is available. Perhaps there is now a better BLE API available than 2 years ago. The most energy-efficient and most accurate method is rewarded.

The other part, this is called triggering actions at a certain distance. I still use Altbeacon to check the range of beacons and the response. A sample code is something like

 @Override public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) { for (Beacon beacon : beacons) { if (beacon.getDistance() < 5.0) { Log.d(TAG, "I see a beacon that is less than 5 meters away."); // Perform distance-specific action here } } } 

So, when you said, you can also get the distance from a specific UUID. I'm building an Altbeacon based method that looks like this (see in the for and if loop):

 private void startRangeNotifier() { Log.i(TAG, "Starting range notifier..."); beaconManager.setRangeNotifier(new BeaconRangeListener() { @Override public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) { if (beacons.size() > 0) { for (Beacon beacon : beacons) { Log.d(TAG, "uuid's: " + beacon); Log.d(TAG, "uuid id1: " + beacon.getId1()); if (beacon.getId1().toString() .equals("b9407f30-f5f8-466e-aff9-25556b57fe6d")) { Log.d(TAG, "uuid id1 distance: " + beacon.getDistance()); } } } } }); try { beaconManager.startRangingBeaconsInRegion( new Region(BEACON_MONITORING_ID, null, null, null)); } catch (RemoteException e) { e.printStackTrace(); } } 

My log output:

 D/Main activity:: uuid's: id1: b9407f30-f5f8-466e-aff9-25556b57fe6d id2: 31807 id3: 59251 D/Main activity:: uuid id1: b9407f30-f5f8-466e-aff9-25556b57fe6d D/Main activity:: uuid id1 distance: 0.2108658568686884 

In my answer, I wanted to introduce the concept that I used, the Beacons project requires patience in general. As mentioned in another answer, here you can also combine the solution with Geofences and ActivityRecognition.

Note. Since the nature of the Bluetooth beacon, the distance is proximity, not absolute, and for a while even the Bluetooth beacon is 1 meter, it may seem 2 meters or 0.5 meters, so keep that in mind

Link Link:

+5
source share

BLE scanning on Android is pretty intense, and it's definitely not what you want to do in the background all the time. If you are working on a background application with Bluetooth stationary devices (à la ibeacons) that you know about the location, you can use Geofences to enable scanning when you think you are in close proximity to the device. If you are not careful, geoprocessing can also drain the battery.

If you do not know the location of your Bluetooth devices, I think you can also play tricks with ActivityRecognition , that is, only periodically scan when the user walks and stops him if the user is stationary / working / riding a bicycle / in a car. Again, the activity recognition element also takes a battery, so you have to be smart.

+4
source share

We need a broadcast event that wakes up our application when a BLE device with a specific Service-UUID is available.

You probably know how to filter the scan results using the Service UUID, so I won’t go into it. About waking up: if your application scans, it is awake by definition. He may or may not be in the foreground, but he is awake.

Perhaps there is now a better BLE API available than 2 years ago.

Starting with SDK version 21, there is a new API that can be used to scan BLE. As far as I know, the only difference is how you access the API, and the basic functions (regarding energy consumption, etc.) have not changed.


About Scan:
It is true that scanning is intense. Even docs talk about it.

The intensity is relative though. It is intense compared to not scanning at all, but it is not intense enough to hopelessly drain your battery. After all, this is called low energy.

Another answer involves monitoring Geofences and only checking when you know that you are in the range of BLE devices. While this will reduce battery consumption during verification , this will require a GPS battery, otherwise it will not be able to control Geofences (well, maybe with cellular / wifi data, but it will not be so accurate).


Depending on how important the time of your scan is (for example, if there is a device nearby, you should know it right away ), or is it normal if it delays a couple of seconds?) You can pause between scans.

Say you scan for 5 seconds, pause for 5 seconds, scan for 5 seconds. Thus, you will scan almost all the time, but only consume about half the battery charge. These intervals can be changed according to your situation. Maybe you can handle the scan for 3 seconds and stop at 10. (note that the maximum time between broadcasting the device is 10.24 seconds ).

I have an application with approximately 50 users who scan with such pauses (scan for 3 seconds, pause for 3, repeat) 24/7 in the background and have not received any complaints about excessive battery use.

+2
source share

If you have a specific BLE peripheral that you want to detect, then find out its advertising period. If you have different devices, find the longest period of advertising. The scan takes longer than the device’s advertising period, so you get at least one advertising message. Repeat this scan at a frequency appropriate for your use case. For example. Your peripherals advertise every second once. You want to detect the device in 5 seconds when it comes to proximity. Then scan 1 s (or a little more). Disable scanning for 4 seconds. This way you can save battery.

-one
source share

All Articles