Our company is developing an android application that uses network communication to send GPS signals from devices. The devices are the same and they are all work tools, so we do not have to worry about battery draining, or etc. Currently the activity has a thread, which communicates with the server. The problem is that when the device is locked and it goes to sleep, the network communication breaks.
I've tried to put a partial wake lock to the onPause method to keep the CPU on, and release the wakelock in the onResume method, but it seems not to work. Any idea how to prevent the sleep, or keep flowless communication between the client and the server?
Unfortunately, it is the new behavior, You can read here:
https://developer.android.com/about/versions/nougat/android-7.0-changes.html
See the Doze section.
When a device is on battery power, and the screen has been off for a certain time, the device enters Doze and applies the first subset of restrictions: It shuts off app network access, and defers jobs and syncs. If the device is stationary for a certain time after entering Doze, the system applies the rest of the Doze restrictions to PowerManager.WakeLock, AlarmManager alarms, GPS, and Wi-Fi scans.
It can be solved by using Foreground Service like mentioned above in comments by #egoldx.
It is surely a bad practice to try holding a wakelock, even partial, all the time.
Related
I am currently developing an android app that gets data from a web server at a user specified interval (5 min, 10 min...). I am using an AlarmManager and a WakeLock. The alarm goes off as expected every 5-10 minutes. The internet connection though doesn't seem to be working during sleep. Most people suggest that I use a WifiLock. Correct me if I am wrong but isn't WifiLock only used to keep WiFi alive? What about 3G-4G mobile data? Does WifiLock keep that connection alive aswell?
Starting with Android 6 due to the new Doze Mode the device enters sleep even with wakelocks, they are ignored.
The way to avoid the device to enter sleep is to start a foreground Service with a non-dismissable notification.
You can't get network access while the device is in Doze mode. If you are hoping to receive notifications or updates from a web service, use Firebase Cloud Messaging, or just defer the network call until the next time it wakes up. You can see more information about Doze restrictions here:
https://developer.android.com/training/monitoring-device-state/doze-standby.html#restrictions
Also, if you are curious about how to check if phone is in Doze mode:
https://developer.android.com/reference/android/os/PowerManager.html#isDeviceIdleMode()
If I have an IntentService that simply updates the SharedPreference, is a (partial) WakeLock needed?
I understand that a WakeLock keeps the CPU awake, but when is it needed?
If you need to keep the CPU running in order to complete some work before the device goes to sleep, you can use a PowerManager system service feature called wake locks. Wake locks allow your application to control the power state of the host device.
Creating and holding wake locks can have a dramatic impact on the host device's battery life. Thus you should use wake locks only when strictly necessary and hold them for as short a time as possible. For example, you should never need to use a wake lock in an activity.
One legitimate case for using a wake lock might be a background service that needs to grab a wake lock to keep the CPU running to do work while the screen is off. Again, though, this practice should be minimized because of its impact on battery life.
Unfortunately, some poorly-coded, malicious, or simply buggy apps might create an abnormal amount of undesirable wakelocks. Other apps require constant Internet access in order to operate in a normal fashion - Facebook and Messenger are probably the most popular representatives. They persistently request information from the web (the so-called "polling" for new events), which is causing subsequent wakelocks.
In other cases, an update to a given app can also cause certain issues, which usually result in partial wakelocks. The latter keep your CPU constantly humming in the background, sometimes without your knowledge, and prevent your device from "going to sleep". That's a pretty substantial prerequisite for anomalous battery drain. Thus, it is advisable to regularly monitor the wakelocks on your device and see which of your apps go harsh on our system's resources.
Read more at:
What-are-wakelocks-how-they-affect-the-battery-life-of-your-Android-device-and-how-to-Greenify
Reference: https://developer.android.com/training/scheduling/wakelock.html
It is needed when you don't want CPU to sleep when user locks the screen for example.
If you have an IntentService without acquired WakeLock it will pause after a while if user locks the screen and it will continue its work when user wakes a device. With WakeLock acquired your service will work even if the screen is locked.
As #My God mentioned, it impacts on battery life a lot, so, use it only when you really need to finish some operation and you cannot wait till user wakes a device.
I am currently developing an app that runs a service from time to time. Currently, the service acquires a wakelock, reads some sensors and sends some information over WIFI (if any). Now what I want to know is weather a wakelock influences sensors and connectivity or not. Is it possible to do these tasks without any wakelock?
Cheers
A wake lock is essentially used to lock the device in an "awake" state, in which the CPU will be on, and the screen may or may not be on.
It is not possible to do these tasks without a wakelock if the phone is in sleep otherwise, as then the CPU is also in sleep mode. However, if the user is using the device for something else, and your app is in the background, you can do these tasks without a wakelock.
Keep in mind that almost everything you're doing is battery intensive (sensors, WiFi, wakelock) and you should not do it too often so that you don't degrade the user's battery life.
I want my application to be connected to server though the mobile connection, yet allowing the device to go into sleep mode. I expect it to wake up when IP packates arrives.
How can this be done? How to receive "interrupts" from the Internet without draining battery?
When you are blocked on a read from a tcp stream the device can go into a deep sleep and when tcp traffic comes in it will briefly wakeup the device, as soon as a bit is read in you start a wakelock until you have received the whole transmission then release it.
Here is an example with web sockets, I've ran this app for over 12 hours in the background with no battery impact.
https://github.com/schwiz/android-websocket-example
The client is here, the blocking read is in the start method.
https://github.com/schwiz/android-websockets/blob/master/src/com/codebutler/android_websockets/HybiParser.java
I've been using long living TCP connections on Android without a wake lock for some years now.
My experience is that when data arrives on a TCP connection and the device is in deep sleep, it will be woken up for a short period of time at least. Waking up the device could take up to ~2 minutes sometimes, but it's usually done within a few seconds.
Now that the device is awake, the receiving process has some time too process the data. Now either the process is able to do so before the device is put back into deep sleep, or the device will be put into deep sleep suspending also the process. The important thing here is that the data is not lost, it remains in the memory and the process is able to resume the work processing the data the next time the device leaves deep sleep. Of course, this means that if the sender awaits an answer to his data, it may take some time, until he gets it.
You could take a wake lock as soon as your network library notifies you that a new message was received. But if you done, then make sure to handle the lock properly, i.e. ensure that it is released at some point and in every code path. I personally never experienced the need for a wake lock, the Android device was always long enough awake to process the request. But your millage may vary.
So this is very old but i ended up testing the behaviour #Flow described and just wanted to confirm that there seam to be arbitrary delays sometimes between the arrival of the data and the wakeup of the device.
I tested using a tcpClient implementation and an mqttimplementation. The idea was to see if there is an requirement of instantly getting the wakelock since this delay appeared in my mqtt implementation.
Test steup:
we have 2 services one running the tcpclient and one running the mqttclient in different apps
Both Services run on the same phone with the same permissions in the background.
The Server sends in both cases an "ping" message.
Our client implementation acquires a wakelock as soon as possible and reads the current Date.
for the tcpclient this is instantly
for the mqttclient the wakelock can only be acquired after the arriving data has been propagated through the networking libraries
we send back an response pong message including the read date
this send happens after wakelock release to see if this further delays the response time
the server logs incoming messages with the arrival and the read date
It appears that in both implementations there sometimes is an arbitrary delay to the call to our code. This makes it most likly that there is a delay to the wakeup of the device and not to the acquire of the wakelock.
this delay can be sometimes seen on all devices(tested on huaweip20light, HMD Global#Nokia 7.2, samsung#SM-N960F)
this delay seams more likly to happen on the HMD device higher api and victim of the stricter battery optimisations android established
Google Cloud Messaging might be what you are looking for:
http://developer.android.com/guide/google/gcm/index.html
I have service running in android to sync files when user wants.
This is not a 24/7 service, only runs for a period of file transfers over wifi, so the user when done transferring files quits the app and therefore the service exits.
So the scenario could be that user has left the mobile and it might get locked/screen off automatically.
Regardless of screen on or off is there a way to ensure wifi is always performing the same with low latency ?
There are multiple apis in relation to this, Wifi lock, Wifi-sleep-policy, screen lock .. People seem to use a combination of them to keep good wireless performance .
Is wifi lock enough to ensure it ? or do I need to use combination of APIs ?
Thank you.
EDIT: this post was helpful
PARTIAL_WAKE_LOCK vs SCREEN_DIM_WAKE_LOCK in download thread
To be on the safe side, a WifiLock as well as a WakeLock would be optimal, with the WakeLock being the more important lock to aquire. The WakeLock ensures the device stays on, and the WifiLock ensures the radio is operating. This should ensure consistent latency. However, you can't expect anything when it comes to data transfers so have your app be ready to handle random connection losses.