Inside my AsyncTask I vibrate the phone in a certain pattern and repeat this until the user turns it off. This works fine as long as the screen is on. If the screen is off, the code still runs but with periodic breaks in between. It seems like Android tries to consume battery with the screen off and only runs code within threads (like my AsyncTask) only periodically. Is that true? Or is this some other behavior? Is there a way I can get my code to run smoothly even with the screen off? Turning on the screen could drain the battery. The vibration is used to notify the user even when the screen is off.
You can use a WakeLock. By using a PARTIAL_WAKE_LOCK you can ensure that even though your screen is off, cpu is running and your code will execute properly.
However, I would like to add that I've never run into such problems with AsyncTask, But if you are running into such problems a wake lock would probably be the solution.
AsyncTask is not designed to handle long running tasks. If you want your phone to vibrate in a specific pattern for a long time, I'd suggest to use set repeating alarm using the AlarmManager.
Related
In our Android app, we have UI component and core C++11 module. A thread is running based on std::chrono::system_clock::time_point, such as below:
while(this->m_ConditionVariable.wait_until(lock, this->m_Object.to_time_point())
== std::cv_status::no_timeout)
{
// ... handle any notify() or arbitrary sleep breaks
}
Execute(); // <--- not being called consistently
Now, we are testing with 1 minute time_point. If the app is in use, then the Execute() is invoked as expected. However, if the app is moved to background or if even the screen is locked, then the Execute()-s behavior is not consistent.
Sometimes, it may work properly every minute for 15 mins and after that it will be invoked after 2 minutes or 3 minutes or 10 minutes, instead of fixed 1 minute. Using debugs, we checked that, the time_point supplied is proper.
Suppose if we run the app in debug mode (using Android Studio) then it works fine even in background and screen locked mode.
Does Android have any threading priority for the app running in background?
Update 1: Basically the background thread is collecting location information. I came across below question, which suggests that in Android, when the phone is locked, the thread execution is halted. Am I stuck to that problem?
App seems to stop working when the screen goes to sleep
Update 2: With partial Wake lock, it works fine. But not sure if that's a good solution. If that's the only way, then I would appreciate strategy for how to use it optimally.
Update 3: If I replace wait() with smaller sleep(), then it works fine even without any Android wake lock. However we are yet to do regressive testing on it.
When the device is idle, the CPU is stopped and any thread running is paused (C++ or Java). If it wakes up for any reason your C++ thread will start working again, hence the random behavior: Other apps or services might wake-up the device every now and then.
Adding a partial wake lock works in your case but that will prevent the CPU from going idle, which will cause some battery drain. If you don't care you can use this approach, if battery live is an issue, you can use the Java alarm API to wake up the device on a regular basis. Then the java API can call the C++ code through JNI.
Android documentation for repeated alarms: https://developer.android.com/training/scheduling/alarms.html
For the update 3, using a small sleep rather than wait(), I suspect android is not going in idle mode while a thread is running, maybe it waits for a small timeout without any thread active before it goes idle. This approach will have the same effect on the battery drain than the wake lock.
My application have a realtime module that should ping the server every 60 seconds. Without this, the connection will be dropped and the device will need to reconnect again.
The first attempt was to use a Thread.Sleep to make the pinging thread runs at the desired frequency. The second attempt was to use the ScheduleExecutorService. Both worked very well, but only when the device was charging or with the screen turned on.
After reading a bit, I realized that this behavior happens because the device's processor sleeps and this interferes on the timers. So, the recommendation is to use the AlarmManager...
After start using it, I noticed the my device's screen started to be turned on frequently and I think that this is caused by the alarmmanager that 'wakes the device up'. I searched o bit to see how to use AlarmManager to execute some background actions even if the device is sleeping, without turning the screen on, but nothing was found.
So, there is anyway to use AlarmManager or other approach to accomplish this? Execute a background task even if the device is sleeping, without turning the screen on?
PS1: I know the battery consumption implications due this approach and the request about not turning the screen on is to minimize it's impact.
PS2: The AlarmManager's intent is being consumed by a background service.
Alarm Manager does not turn the screen on. From the docs,
When an alarm goes off, the Intent that had been registered for it is broadcast by the system, automatically starting the target application if it is not already running.
I am using it in my code and it does not turn the screen on unless I explicitly set a wake lock policy that turns it on. Take a look at WakeLock
The last 3 are deprecated as of API level 17.
I recommend you to use a PARTIAL_WAKE_LOCK for your task. or you can take a look at WakefulBroadcastReceiver
If you are using onReceive() method, that may be acquiring your wakelock. Remove the WakeLock parameter in onReceive().
I used this tutorial http://forum.xda-developers.com/showthread.php?t=1732939 to create a simple clock widget.
Sadly it's not running very well. When the screen is turned off, the widget won't update anymore so it won't show the corret time.
So, how can I update the widget even if the screen if turned off?
Take a look at Repeating Alarms:
They operate outside of your application, so you can use them to trigger events or actions even when your app is not running, and even if the device itself is asleep.
https://developer.android.com/training/scheduling/alarms.html
Or at "WakeLock":
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.
https://developer.android.com/training/scheduling/wakelock.html#cpu
Using the first approach can help you to get your point.
I'm developing an application which needs to run small chunks of code frequently (once every two seconds, for example). I've tried to make it work using the simple Thread.sleep() (or android.os.SystemClock.sleep() to avoid interrupts, and finally I've tried with Timer and Handler), but the result is that the time that the program sleeps is random (or it simply doesn't run if I use Timer or Handler as the system discards they messages when the screen is off), as the system goes to a deep sleep mode during screen off.
For example the code works right if I have the phone plugged into the charger, or is playing music (that avoids the deep sleep mode), but when the phone isn't doing anything the time can grow from two seconds sleep up to minutes of sleep.
From https://groups.google.com/forum/#!topic/android-developers/Eqwp8Uiy2f0 seems that the only alternative is to use the AlarmManager to force the wake, but that way will probably cause too much battery drain.
Is there any alternative?
If not, is there any way to detect when the system goes into the deep sleep mode?
It is too late but may be useful for somebody else.
Yes, Timers does not work in deep sleep mode.I think there is no other better way than AlarmManager to run something periodically in deep sleep mode.
Also, as your frequency is just 2 seconds I think you may have to go for exact alamrs (setExact() ) as the regular alarm may not serve you better if your requirement is critical in time. And sometimes even setExact might not capture the wake lock I observed. So you have to acquire your own (PARTIAL_..) wake lock and, do stuff and release the lock.
But is it must that you have to run evvery 2 seconds ?
If not continue using Timers which will continue working automatically after the device wake up.
Take a look at Should I use AlarmManager or Handler?
I would like to know if there is any way to turn off the screen on an android device on for example 19.00-22.00 every day. I have some tablets running in kiosk mode, and i want the screens to turn off when no one is using them and the store is closed.
Thanks
Screens will turn off automatically, if you have that set up properly in the device settings.
You can use AlarmManager and a WakeLock to arrange to keep the device screen awake during business hours. Have the AlarmManager start up a service that acquires the WakeLock and waits until closing time. You will need to use startForeground() in the service to prevent Android from killing off your service.
In the real world, this implementation would suck, as it forces you to keep a service running all the time -- if you let the service shut down, you lose the WakeLock and can never release() it, so the screen will never shut off. So, outside of this sort of kiosk thing, I do not recommend this technique.