We are working on an Android app that makes GATT connection to BLE devices and writes some characteristics. Our current approach is to scan for devices (startLEScan on Android 4.3 and 4.4. devices and startScan on Android 5.0+) every few seconds and connect to device when discovered.
This solution works but it drains a lot of battery because we need to keep wake locks (or trigger alarm manager every few seconds) for the scanning to work when the phone is in sleep.
Is there an way that Android can notify the app when the BLE device is discovered instead of continuously scanning for devices?
iOS app works great because iOS wakes the app in background when there is any BLE device nearby, which saves a lot of battery.
Wondering it there is something similar on Android to keep the battery under acceptable limit.
Just for reference, we have also tried the Alt-Beacon library but found
that it internally usages alarm manager and if we set alarm manager to trigger every 5 seconds, it consumes 7-8% battery every hour.
Related
I have a security system where moving a Bluetooth LE device causes my android application to do some work. After some of the newer Android updates, I believe API 26, I could no longer get these updates if the Android device's screen was off. I was trying to think of a way around this and came up with an idea:
What if I paired the Android device and the Bluetooth device - would this allow for the message to be received when the Android screen is off?
Previously, all my BLE devices were part of a mesh, so I would regularly have the Android app check for changes in the mesh and turn the screen on to notify the user if needed. Now, because of the background execution limits introduced, I must require the Android device to have the screen on at all times, which leads to the death of display over time.
I'm not that great at programming in C, which is the language the BLE chips are programmed in, so I wanted to ask this first before spending hours just to see this NOT work. So, just to repeat the question: Will having a BLE device paired with the Android device allow a message through these restrictions when the Android screen is off?
If not - is there a way I can make this work?
Thank you for any info!
Use notifications instead of advertisements. This will deliver data instantly and works even if the screen is off. Newer versions of Android have introduced more restrictions for BLE scanning when the screen is off.
Use connectGatt with autoConnect set to true to automatically connect and reconnect in case the connection drops.
Use a Foreground Service in your app process to prevent the app process from being killed. If your app process exits, all Bluetooth connections are dropped as well.
You could use CompanionDeviceManager to gain some extra permissions.
You don't really need to be paired but it has some benefits such as faster connection setup and correctly remembering the address type (flaw in the API that this is missing).
I'm using BluetoothLeScanner to scan for BLE devices, which I start using:
startScan(null, settings.getScanSettings(), scanCallback);
Every once in a while, a call to startScan() does not discover any BLE device, even though some devices are actually advertizing (They are discovered using nRF Connect app).
When this happens, the next call to stopScan() and startScan() does discover devices.
I know that since Android 7, the number of start and stop scans is restricted to 5 times in a window of 30 seconds. However, I've noticed the problem sometimes also occurs if no stopScan()/startScan() has been called for more than 30 secs.
Has anyone experienced such issue ?
Could it be something else my app is doing while starting the scanner that could the scanning to fail ?
I have this problem using Android 10 and lower versions.
Android phone limited BLE scan duration to save energy. So you can not scan BLE advertising for a long time. It is system limitation so APP layer have no way to change that.
In older phone (maybe under 4.4) do not set the limitation, but it will make the phone getting hot.
If you want to scan BLE advertisement for a long time, change your design is a better way.
I faced the Android scan stopping issue in background when I am developing my COVID contact tracing app for my company. Here is what I have tried:
Add foreground service
Disable all the battery related optimization options in the phones
Enable the application running in background
Tesging devices:Galaxy S20 and Xperia with Android 10, Huawei with Android 8.
The scan stops immediately when going to background if you don't disable those battery optimization settings and application background update. After you disabled those settings, the scan can run about a couple of minutes(~5 minutes), then still stops. From the blog of David:http://www.davidgyoungtech.com/2017/08/07/beacon-detection-with-android-8, it seems that it is impossible to scan continuesly in background, because the JobScheduler will restart every 15 minutes while each scan lasts ~10 minutes at most. Is this the reality, or this is the best solution that I can scan 10 minutes at every 15 mins cycle?
Background beacon detections are tricky to implement because many small issues can trip you up, and the specific issues vary by Android version, Android manufacturer and sometimes model. While Android 8+ restricts background ranging to every 15 mins using the Job Scheduler, if you add a Foreground Service, you can unlock unlimited background ranging.
A few tips:
Focus first on the Galaxy S20 as Samsung behaviors are better documented and closer to vanilla Android. (Ideally you would test on a Pixel device first.) Only once it works on Samsung, move on to the others.
Using the Android Beacon Library reference app configured with the built-in foreground service, I have seen detections of a standard iBeacon or AltBeacon continue on a Galaxy S10 indefinitely in the background, even with a 1.1 second scan period. See if you can reproduce the same.
Be careful of Doze mode. If the CPU is put to sleep due to the phone being motionless with the screen off and not charging, your detections will stop. You can defeat Doze mode with wake locks, but it has a punishing impact on battery usage. You are better off accepting its limitations and keeping your phone in motion periodically during testing. If you want to get logs to see what is happening, use ADB commands to disable charging when connected via USB or learn to use ADB over WiFi.
We have a device that need to be started at night, the device is started thanks to a bluetooth command sent by a mobile application. It's possible to send this command while the app is in the background and keep monitoring the device (i.e. receiving data), for example, for 30 minutes?
If it's possible what would be the ways to implement this feature in iOS and Android?
Update: Think about a sleep tracking device; the problem shouldn't be to scan all night because the user must connect the device before go to bed (and eventually try to automatically reconnect to a known device, without the need to scan). I'm asking if it's possible to stay connected and send/receive data while, for example, updating an internal database all night.
Several thing to take into account about Android BLE system development, read this for more information: https://blog.classycode.com/undocumented-android-7-ble-behavior-changes-d1a9bd87d983
BLE Scanning has an abuse prevention since Android 7. What does this means?
Prevention for an app stopping and starting BLE scans more than 5
times in a window of 30 seconds.
Long-running scans are converted into opportunistic scans. (30 minutes).
About the background process depends on what type of service you want. You can start a foreground service with a notification or you can start a Job which runs always in the background with no notification.
If you can be more precise on how the system is going to work I can give a more detailed explanation.
I am developing an android application that uses Bluetooth Low Energy to receive data from a peripheral device.
The device itself sends the data as part of it's advertising message and it could send the message at any time.
So the applications works by continuously scanning for BLE devices.
When the screen is ON the application receives scan results as intended.
When the screen is OFF it appears that it only receives scan results every 5 seconds.
I guess that the phone is trying to optimize for battery life but this app is mission-critical so we can not afford to lose messages.
The scanning is done by a Service which is set as a 'foreground service' so that the OS knows that it is important.
The service also acquires a PowerManager.PARTIAL_WAKE_LOCK but that does not seem to help.
The application is excluded from battery optimizations so that it does not enter Doze or deep sleep mode.
The application is using the following ScanSettings:
ScanSettings.SCAN_MODE_LOW_LATENCY
ScanSettings.CALLBACK_TYPE_ALL_MATCHES
ScanSettings.MATCH_MODE_AGGRESSIVE
ScanSettings.MATCH_NUM_MAX_ADVERTISEMENT
I am working with a Galaxy S7 but I have been told the same behaviour happens with a Galaxy S7 Edge.
I have tested with other non-samsung devices and they work as intended (continuously receiving scan results when the screen is OFF).
The question: is there something that I, as a developer, can do to make the BT adapter deliver scan results continuously even when the screen is OFF?
Samsung automatically change scan mode to low_power if screen is turned off. It's their customisation on their Android OS, so unfortunately no way to change it.