According to Android docs:
A Service is an application component representing either an application's desire to perform a longer-running operation while not interacting with the user or to supply functionality for other applications to use.
But my service get killed very quickly - around 10 seconds - when the user leaves the app or the screen gets turn off. It seems according to Android Kotlin Foreground Service stops after some time that you need some sort of mechanism to prevent the phone from getting in doze mode.
So, what is the purpose of having a service without a wake lock? And why does the documentation never mention something remotely related to wake lock when dealing with services?
You can have a Service that is doing work for an Activity. If the user navigates away from the app or dims the screen or ignores his phone long enough for it to be clear that he isn't looking at it, what is the point of the Service continuing to run? The user isn't looking at the Activity, so processing in the Service is not important enough to keep the phone from sleeping.
On the other hand, if you have a Service that is performing important work and you need to keep the phone from going to sleep, then you obviously need to get some kind of wake lock or use some other method to keep the phone on.
These are 2 different scenarios with different requirements.
Related
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'm developing a small utility app that scans 2D barcodes, and then submits each barcode to an IntentService where a longer task is performed.
When the activity is shown, it should prevent the device from sleeping, until the barcode is processed in the service. If the service finishes the processing, it stops itself, but the activity should still be visible.
I'd like to hold a SCREEN_DIM_WAKE_LOCK WakeLock during the activity lifecycle, but as this type doesn't prevent the CPU from sleeping, I'd also need to acquire a PARTIAL_WAKE_LOCK in the activity when a new 2D code is scanned, and release it in the intent service after it has been processed.
The SCREEN_DIM_WAKE_LOCK purpose is to avoid the user the inconvenience of pushing the power button each few seconds to wake up the device and be able to read a new barcode. The user will have to read a great number of codes one after another and the activity should be around even for the short intervals where there's no user interaction.
I know in Android there's no 100% guarantee of the app being on top, not closed, or foregrounded due to several conditions my app can't control, but I'd like to go as far as I can.
So it is possible to hold multiple WakeLocks? Where could they be declared to be accesed both by the activity and the service? (Singleton, extending Application?)
It is possible to hold multiple WakeLocks. In fact it's done all the time when multiple applications sync at the same time when the screen is off. (Imagine your GMail and Facebook apps sync at the same time when the screen is locked. They don't know about each other will have different WakeLocks. May or may not be different types of WakeLocks)
Android will make sure everyone's expectations are met (maximum battery drain in other words.)
In my opinion, I think you're over-thinking the fact that you need a SCREEN_DIM_WAKE_LOCK as this can accidentally drain a LOT of battery, but I may be wrong depending on your use case.
So the short answer is YES. You can hold multiple WakeLocks and Android will (should) act as expected. Only thing to keep in mind is that you release both Wakelocks properly.
In the issue of getting on top of the screen, I think you should release the WakeLock of your activity when it goes to Paused state (when somehow another activity is on top, or use intentionally press the power button). Because at this point, user is interacting with another app, and you should respect it and let it control its own behaviour. You don't have to give up the partial wake lock from your service until you're done.
Hope This Helps.
I am relatively new to Android, so what I am asking may seem obvious (although I have read all the similarly titled questions, and have searched extensively). I need to monitor the accelerometer continuously for long periods. Two approaches have been suggested:
1) acquire a partial wake lock that is held the entire time the acceleromtere is being monitored; and
2) monitor the accelerometer in a foreground service.
The first approach appears to use a lot of battery life. The second approach should result in a service that is only killed rarely, but I'm not sure what "rarely" means. Which approach should be used, and are there alternatives that I should consider?
Holding a WakeLock and a foreground Service are not really related and shouldn't be compared are to which direction is best.
Android OS is built to swap out processes based on a variety of factors. This means your process might get killed at any point by Android and it provides a framework to help you, the developer, to ensure your app can save and restore its state when this happens.
A WakeLock simply prevents the CPU from sleeping which helps save battery when the phone is not in use.
Now, a combination of both would help you achieve what you want but at great user cost. I wouldn't want an app in my phone to keep the CPU constantly running or a notification icon to show up constantly in the notification bar (that's what a foreground service does).
Keep in mind, starting a service in foreground mode does not guarantee your app will not get killed. It might still happen albeit rarely.
What is it you are trying to achieve here? Why keep monitoring the devices accelerometer? Perhaps you should only monitor it only when an Activity of your app is in the foreground instead.
I had exactly the same need and problem. I believe the solution is to use both a partial wake lock and a foreground service. Android will try not to kill a background service that holds a wake lock but is free to kill it when it needs the resources and possibly restart it later. That's fine for a lot of purposes but at least in my case that is not good enough. Putting a service into the foreground state is the way to tell Android that that killing it is unacceptable. Yes, it might still happen in extreme situations but that would now be a violation of the API contract whereas with a background service Android is free to kill it. You should therefore probably code as if that that will never happen but just know that this is a possible but probably rare error.
My application sends an sql insert query everytime the telephone is tilted at more than 45°
I need either to stop the user from quitting the application or have it still running in the background so that it still sends the queries
basically I need the application to be running all the time, any ideas?
thanks
You should create a Service. This will run in the background executing the SQL inserts while leaving the user free to interact with their phone and answer calls. Remember to keep in mind battery usage and CPU resources while it is running.
Another common technique is to add a status bar notification while the service is running. This informs the user that the app is still running in the background, and allows them to bring a relevant activity back to the foreground by selecting it.
One thing is for sure - do not prevent the users from quitting the application. There is, however, a wakelock that can keep the processor on despite being out of the app, using the wakelock flag PARTIAL_WAKE_LOCK. Look into services and wakelock.
Look here for more information on PowerManager and WakeLock, and here for more information on Services. This link is also pretty helpful regarding a demo on how to use a Service, and this StackOverflow question displays how to properly setup a WakeLock (although you'd want to replace SCREEN_DIM_WAKE_LOCK with PARTIAL_WAKE_LOCK for your purpose).
I want to make an application which when it is on "idle state" it must stop doing something. Application enters in idle when user doesn't interact with the application for a number of seconds (ex. 50). Are there some android classes for this or how to do this in a simpler way?
Application enters in idle when user doesn't interact with the application for a number of seconds (ex. 50)
There is no built-in concept of "idle" in Android, other than the device going into sleep mode. You can watch for ACTION_SCREEN_OFF broadcast Intents, but that will be for the whole system, not just your application.
If you have no "background" task processing, you really have to understand the Android Activity lifecycle. You don't have to care about your application going "idle". You have to always keep in mind that your application can be put to sleep by the system AT ANY TIME.
Really read carefully the developer guide.