Question
I am wondering if we need to aquire the WakeLock or if the service.startForeground() command does that anyway for us? I didn't find anything in the documentation.
Goal
We want to remove unnesessary stuff which might slow down the service start as we want to start capturing the sensor data as soon as possible and as the service might be restarted frequently.
Context
We're developing an Android library to capture sensor data with ~ 200 Hz for up to a couple of hours (research environment). Right now we aquire a WakeLock and start the capturing service as ForegroundService to make sure our capturing isn't stopped when the device is not used.
To answer my own question (if no one else finds more details on this):
In my understanding "foreground" just describes that the user would notice if the app was killed e.g. when browsing a large page. For this reason the system is asked to try to avoid killing the service.
Just because a foreground service is running probably not implies
that the CPU can't go into deep sleep mode.
In order to collect sensor data all the time from user-defined start to stop we still need to aquire the WakeLock ourselves.
No, wakelock can be used to make sure your foreground services run when device goes to sleep
If you must use partial wake locks, follow these recommendations:
Make sure some portion of your app remains in the foreground. For example, if you need to run a service, start a foreground service instead. This visually indicates to the user that your app is still running.
https://developer.android.com/topic/performance/vitals/wakelock#best_practices
Related
I have some questions concerning wake lock and services
1- I try to test my service when the screen is off and not acquiring the wake lock, i was expecting that system will kill my service but it didn't happen, so what is the purpose of wake lock?
2- I want to know when then the system goes into doze mode, is it when i turn off the screen or after some time of turning it off? and what happens to my service in this case? and how to know that the system is in doze mode?
3- I know that since Android O normal background service will be killed after nearly one minute, i tried to test that by making intent service and make it running for more than one minute, it was already killed but started again and continued execution, so what is the purpose of killing it and starting it again?
4- does doze mode affect foreground service? and should i acquire wake lock in case of foreground service or is it acquired by default?
Code of Intent service
Logcat
I know they are lots of questions but i am confused with these topics
thanks in advance
The device may fall asleep if the user is inactive and nothing is keeping the device awake. A WakeLock is used to ensure the device stays awake.
You may check those links for additional information: Good answer Official Documentation
Information about Doze mode, Standby and some other things that you may be interested in:
link
Background Service Limitations: While an app is idle, there are limits to its use of background services. This does not apply to foreground services, which are more noticeable to the user.
link
Processes which have a current running foreground service are supposed to be unaffected by Doze. Bound/unbound, started/not-started, and wakelocks do not affect this whitelisting process.
link
--- Update ---
Some things could change from the moment of those questions were asked, so prefer to read documentation or search for the actual information about it. Also it's a good idea to check information about modern solutions for back ground like WorkManager.
I am writing an application which can continuously monitor the input from mic, process it (Processing algorithms are written in C++) and save (log) or playback some events of interests. I am testing my app on Android L and Android M phones.
Application works fine as per my requirement with issue in following use case:
Turn the monitoring on
Press home button to send the app in background
Ensure device is not charging
Wait for some time
After some time (About 15 min) I get following message in logcat:
Suspending all threads...
To overcome the problem I tried following:
Hold wake locks (PARTIAL_WAKE_LOCK)
Use another level of thread spawning using an asynctask
Set FLAG_KEEP_SCREEN_ON in my activity
But none of them seem to work. On iOS I can achieve the desired functionality of this use case using highlighted flag in infoplist.
Is it possible to do something similar in Android? (I believe audio players already do something similar)
I hope this won't be a complete solution for you. But i will try to give a solution that will extend the lifetime of your application. First of all it is not possible to keep an application alive all the time. It is against the Android's rule, as when the system needs resource (for foreground app) it may stop your application. But you can extend the life time of an app by pushing the functionality into the service. Below is a solution for you.
Create an Activity which has 2 button to start and stop recording.
Create a Service and place a Public static variable as a flag set to either true or false.
In activity use the above static field to check if the service is active or not and enable or disable the start recording button according to it.
Use the button to start the service, inside the service acquire a Partial Wake Lock and start a Thread and do your recording. I hope you don't want to redeliver your Intent to the service as it is used to just start a thread for recording. You can use START_NOT_STICKY which restarts the service only if there is a pending start call. If you really wanted to redeliver your intent with recording and append it with the new one, i would say it is point less as you don't know when the service would be restarted and you may miss some recording at that time.
As you hold the partial wake lock it will continue to run until the Foreground app needs resource. As the service has higher priority than the background app.
In onDestroy()Stop the Thread by using the interrupt flag (Save recording too by checking the interrupt flag), set the public static field to FALSE and release the wake lock. You may start the recording from your activity when this is done.
By using FLAG_KEEP_SCREEN_ON in your activity you are just telling the system to "Keep the screen on when i am in this activity". If you hit home or switch to another activity it will not work. I hope games or apps like video players use this to keep the screen on.
I should also point that by keeping the Partial Wake Lock for longer time it may drain your battery considerably. Also you could advice your users to stay in the activity for continuous recording if you use the FLAG_KEEP_SCREEN_ON.
I would although advice to Start an Intent Service, acquire a partial wake lock and start recording. As it will stops the overhead for creating a new thread and starting or stopping it when needed.
Also in iOS, I think the system GC the APP for resources when your application shifts to the background. That's what i remember when i was learning iOS.
I hope my solution helped you little bit to extend your application's life time. Thank you
I've been looking through many questions about services, but I couldn't find one that suited me.
I need a service that both starts on BOOT_COMPLETED (not bound to an Activity) and runs ALL the time (therefore I can't user AlarmReceiver). I know it might drain my battery but so far I don't care. It is just for research purposes.
I have a service that monitors sensor's data. What I managed to do so far was: either start the service as a regular Activity, but it runs only for +-20s and it is stopped (I think the SO cuts it down to release its memory); or start a service that runs in foreground. It worked to keep the process running, however the class that actually runs the service somehow was not started, besides an annoying notification which is required.
The code I refered as the one that runs the service in foreground was taken from here:
Implement startForeground method in Android
I mean, how does an app like WhatsApp run constantly? Is it running in foreground? Because looking at Settings it seems the service is very stable, and it does not show any permanent notification, since it is not possible for a foreground service run without one.
( How to startForeground() without showing notification? )
Any advice?
You can use a WakeLock. But please remember, with great power comes great responsibility (to release them again and not over-use them).
But for now, just acquire a hefty WakeLock and only release it until you are done. This should keep your device's screen and CPU awake and allow you to do whatever it is you want to do.
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).