Doze, different between Marshmallow and Nougat - android

Currently i reading in official google doc news about Android 7.0
I can not understand a few things.
They wrote Doze improve battery life by turn off network and CPU when user block the screen.
But how this works ?
1.I have Marshmallow in my device, and when my phone is blocked, i still get notifications from app with network (e.g. Messenger).
2.Second thing they wrote Nougat have improved this more by again CPU and network. So what is exacly differet ?

I have Marshmallow in my device, and when my phone is blocked, i still get notifications from app with network (e.g. Messenger).
SMS does not usually go over the Internet, assuming that is what you mean by "Messenger" (many apps use that name). Plus, high-priority FCM push messages work despite Doze mode.
Second thing they wrote Nougat have improved this more by again CPU and network. So what is exacly differet ?
There is a "Doze on the go mode" that kicks in even if the device is moving. This is covered in the documentation and in the documentation.

Push Notifications will still get through, but most services will stop running after a while if you leave your phone sitting on a table with the screen off.
For example Spotify still keeps running smoothly because it has a foreground notification. The battery savings come from when the OS can shut down most systems such as internet and geolocation as well as avoiding running other services for increasingly longer periods of time,for example reaching stretches of hours by the end of a typical user's sleep at night.
Now they're mainly doing what they were saying for a long time: background services have no guarantees of how long they will run. The biggest unintended consequence is that sometimes when they wake up there's no internet or geolocation is not available. And the time they run is less predictable.
There's still ways to wake up and perform tasks with perfect predictability using exact alarms or push notifications, depending on where the event is generated. But for most cases the recommended solution is using job schedulers.

Related

Do a guaranteed execution of code every 15min even in doze mode

I have an active-monitoring healthcare application that needs to be synced with different BLE devices every 15min in order to collect vitals and essential data. For this, I am using a ForegroundService with a Notification, Additionally, I have taken the wake-locks, and unrestricted power plan for the app as well with 15 min Periodic WorkManager Job as a safety check which basically triggers the same ForegroundService if somehow service is killed while device goes to idle or doze mode.
Problem
Most devices seem to be working fine, However, most Samsung, Huawei, and Xiaomi devices fail in doze mode. the sync window is increased by 30-120min.
Requirement
I want devices to sync reliably even in doze mode. I want to know possible solutions which may achieve this goal. Since data is important for real-time monitoring and triage a Battery-Tradeoff is acceptable as opposed by DOZE mode. Is there any special permission or mechanism I can use to achieve this?

Android Beacon Library: Keep BeaconTransmitter running "forever"

is there any way to keep a BeaconTransmitter instance sending forever?
The Problem:
I want a RPi detect when I am coming home independent of Wifi running or the RPi even having access to the internet (e.g. it could then turn on all routers etc., when it detects the phone).
I have a minimalistic app on my android phone sending out an iBeacon running and the beacontools Library on the RPi detects it. This is working well, in principle. (Although I know it's supposed to be the other way around, but I again, I want the RPi to be able to do "stuff" without having access to the internet, what the phone cannot do).
However, the power management(?) on the Android phone seems to stop the transmission, the latest after a few hours (even if the App is "not optimized" for battery usage). I am not even sure if this is because of the battery optimization or something else.
Solution so far:
I am using a PeriodicWorkRequest that checks every 30 minutes (I read somewhere this is the minimum time), if the beacon is still running and relaunches it, if it is not.
This also works as expected, but of course, I keep coming home in the time slot when the beacon transmission has stopped and before it is kicked off again by the WorkManager. ;)
A cleaner way would be to "intercept" when the BeaconTransmitter is killed by PowerManagement/BatteryManager(??) or something. Is that possible?
Those covid tracking apps are using something (I hope) that ensures continuous transmission, but I know that Google/Apple had to implement something fundamental to allow those to work, and of course, I cannot use the covid-tracking itself because it is anonymous by design.
A precise answer will vary by phone manufacturer as many OEM's fork Android to kill long-running apps in the background. See here for a summary of challenges by OEM.
For vanilla Android (Pixel phones, many Nokia Android Once devices), Motorola and even most Samsung devices, it is sufficient to keep a foreground service active and have Location always runtime permission. My BeaconScope app uses this foreground service technique, and I typically see a transmitter keep going for weeks on a Pixel or Samsung device. Be sure you grant "Always" location permission to the app for this to work.
You can see the code needed to set up the foreground service in the Kotlin reference app for the Android Beacon Library. The comments indicate that the foreground service is useful for continuous beacon scanning, but it is equally true that it is useful for long-term beacon transmission.
Without the foreground service, the beacon transmission will only last about 10 minutes after the app is put to the background on vanilla Android, at which time the app will be killed.
The problem with a periodic work request or a job service is that they can run at most every 15 +/- 10 minutes on Android. So if the transmitter is killed every 10 minutes you will end up with gaps of up to 15 minutes without transmission. On Android 8+ you have no choice but to use a foreground service.

Android Long Running Wi-Fi Scanning Service

I have been following https://developer.android.com/guide/topics/connectivity/wifi-scan guide in order to create a Wi-Fi scanner. I am using a foreground service with a handler to call wifiMananger.startScan(); every 30 seconds (I tried with 15 minutes).
Everything works great for about 2 hours then suddenly WifiManager.EXTRA_RESULTS_UPDATED boolean returns false and the wifiManager.getScanResults() are not getting updated. Then as soon as the phone is plugged in it starts sending results again. (No, it is not low on battery)
I have battery optimization turned off. I have all of the required permissions allowed. Locations is turned on with Wi-Fi scanning enabled. The device I'm testing on is a Samsung S7 Edge running Android 8. So I know it's not the new OS. (I also tested with a Nokia 5.1 running Android 10 with pretty much the same results).
Does anyone know why this is happening or has anyone encountered this issue before?
Thanks in advance.
Updated: In case of your problem, since you are using exactly 30 seconds due to some problem there might be more than 4 time in a 2 minutes period, make it like 35 seconds and test the result.
Original Answer: From this WifiManager startScan throttled in P Beta (Developer Preview 2) :
"Call Limitations - Throttling
We are further limiting the number of scans apps can request to improve network performance and improve battery life.
The WifiManager.startScan() usage is limited to:
Each foreground app is restricted to 4 scans every 2 minutes.
All background apps combined are restricted to one scan every 30 minutes."
It is said that this restriction is due to the battery drain, so it is normal to remove the restriction while charging.
Read more about throttling in official documentation.
This is because Android OS enters the infamous "Doze mode". I recommend you to look through the official documentation/explanation.
Unfortunately, there is no way around this. It will also affect any kind of a foreground service and pause it for longer periods. Doze mode will only trigger if the screen is locked and the device is not plugged in.
I encountered the same issue on my project and we implemented a periodic check. If the screen is locked and device not plugged in for a longer period of time, we show a notification asking the user to either plug the device in or open the app so the service could keep working. The implementation is a bit lengthy, but if it is what you decide to go with, I can update the answer with some of the code (using the AlarmManager within a BroadcastReceiver to achieve this).

How to keep alive socket connection in android 7.0 and above?

I am developing multiplayer game using Socket.io library. it Works Well.
But, in android 7.0 and above, system automatically suspend all network work when my app is in background. (And I must need to keep alive my socket connection).
I research about it as described here.
but, i can't understand. So, Please provide solution for that.
Unfortunately there's bad news and some good news for you on this.
Bad:
Since android marshmallow and above, there's a concept of a doze mode. If the device stays put for some time (can't confirm the duration for this and not disclosed by google), the device will go into doze mode and will suspend all network activity. There will be short maintenance windows where in you will be able to do syncs and stuff. Small workaround, do not target 23+ apis, i say small because i have observed this to not work on some phones. Another way to potentially bypass this would be to whitelist your app from battery restrictions but according to google guidelines, i don't think your app will qualify for that.
Worse news is that start from API 26, background services will also get suspended completely when app is totally backgrounded and has no visible component (a notification or a foreground service etc...). So oreo will be worse.
Good:
You might not really want to constantly keep the socket open. Instead opt for bursts of syncs. I personally have a job run every 30 - 60 mins or so to try and sync up.
You can leverage the JobScheduler apis and it will automatically handle the doze modes and stuff and you can make them run periodically when there is internet connection. While the job is running, you can connect to your server, do your thing and shut the socket. This is what google wants and is pushing all devs towards.
UPDATE 19-Apr-2021
WorkManager is the new and the best way to deal with doze mode and background limit restrictions.
Another alternative would be to have a foreground service with an active notification displayed which would constantly be connected via your socket. This will be visible to the user and it will not only annoy them that you are constantly using their data, it can also be bad for the battery. Alternative to this again is using the job scheduler to schedule and run a foreground service periodically so as to be transparent while also syncing your data every once in a while. The latter approach is what WhatsApp does, they have a job running which syncs all incoming messages with a foreground service once in a while.
In Short:
You will not be able to keep it alive always. You can try doing it in bursts using one of the methods that i described and know currently (maybe there are other alternatives that i don't know, i have tested these and they work) You will have to compromise, sorry.

Keep app service active during device sleep

So I've made an Android video-calling app that tries to be available in the background so that the user may receive calls when the screen is off. I've noticed however that the app would be paused when the device went to sleep.
The solution I've found that worked was to rewrite everything to a service and then request a wakelock so the service wouldn't be paused during sleep.
Surely, since there are so many of these types of apps, there is a more elegant way to do this? A periodic check wouldn't work since you would want to take the call in real-time.
It depends on the Android version, for version older than 6 a partial wakelock is enough to keep the device awake, for Android 6 you also need a foreground service, that's a Service that calls startForeground() and shows a notification, but to keep the device awake has a big impact in battery usage.
You do not necessarily need to transfer all the code to the Service due it is the whole application that stays awake.
A more elegant solution to replace all this would probably be to use Push Notifications, it is what most messaging applications use. Firebase has Push Notifications.

Categories

Resources