I'm making an app that starts a Service that sends SMS message periodically under specific conditions. It all works, but I have problems to run the job (check conditions + message sending) periodically every minute when the phone is in "standby" (display turned off). With screen on it all works without problems.
I tried using java Timer and TimerTask, but when the screen is off nothing works and when I turn it on, all skipped task are executed in a row (for example, if I turn off the screen at 20:00 and turn on it at 20:30, TimerTask is executed 30 times at 20:30).
I tried also with Handler using Handler.postDelayed method. In this case nothing is done, and when I turn on the screen skipped task are not executed.
So, how can I run a Runnable every minute also when device screen is off???
You can try the AlarmManager
http://developer.android.com/reference/android/app/AlarmManager.html
Related
I want to show seconds in a watchface. In normal mode as well as in ambient mode. General Handler thread Handler handler = new Handler( /* Runnable{ invalidate(); handler.postDelayed(this, 1000);}*/ ) Works fine to update time and show it in screen while in normal mode but it sleeps and slips so far away and executes in random time while in ambient mode. Well this is nothing new and android doc and everyone says to update screen in every minute instead of a second. But I want the watchface to show seconds and that should be updated in every seconds despite battery life. And I can not find a answer for this.
I definitely tried ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();. All gave similar result and among these ScheduledExecutorServices schedule at fixed rate method gave worst performance. In my opinion AlarmManager is overkill for this purpose. The thread is created in onCreate method and is not changed.
Now someone please tell me a way to update the screen in every second while in or out of ambient mode.
Note: All thread works fine on wear OS emulator but on actual watch it shows this behaviour, that is executed in a random time, like in every 20 seconds.
Recently, I have been working on scheduling repeated tasks in background threads in Android application. I started with AlarmManager but due to its inaccurate triggers at specified intervals, I decided to use other JAVA and Android APIs.
I started with Timer and then ScheduledExecutorService and lastly ScheduledThreadPoolExecutor.
The problem with Timer is that it does not always run all the background tasks at right intervals. I had used it to run 3 background repeating tasks out of which only 2 were getting triggered. The third task was triggered after a couple of hours and to catch up with all the previous misses, it was triggered within 10ms (although the interval was 5 mins)
ScheduledThreadPoolExecutor is more accurate in triggering the repeated background tasks. But the problem with it is that it does not trigger the background tasks when the device is in sleep mode (screen off). The same is the behavior with Handler.postDelayed() which pauses the execution of tasks when the device is in sleep mode.
Now, I have reached a dead end. I am looking for a solution that could help me run my background tasks concurrently and without any interruption due to device going to sleep mode.
Please advice.
I am working on an application which triggers an action (say toast message) every 10 minutes after the screen is ON and stops the action after the screen is OFF.
I have used TimerTask for this purpose.
Shall I start using AlaramManager instead of TimerTask or shall I keep using TimerTask ?
I know the difference between the two but can't figure out which to use.
Cant' agree with the nikis' answer
Timer and AlarmManager are solutions addressed to satisfy different needs.
Timer is still a "task" that means this is a thread of your application that means that some component of your application must be running on device to keep timer alive.
If you set timer for 10 minutes events - you can't be sure if your application will not be disposed by system in some moment. If device will be turned into the sleep mode your timer can be stopped. To prevent behavior like that you have to use PowerLock's and drain battery
AlarmManager is system service (runs outside your application) that means that the pending intent will be sent even if your application is killed after setting the alarm.
Some examples:
You have to blink some "led" on the view every 1 s - use Timer - you need it only when application is in foreground, there are short intervals - no point in using AlarmManager for task like that.
You have run some task once after 10 s - Handler.postDelay(); will be the best solution for that, and the job will be done on main thread (UI).
You have to check every 10 minutes if there is some new content on device that you are supposed to push to the server - use AlarmManager - your application does not need to be alive all the time, just let system to start job you want every 10 minutes - that's all.
In most cases you should definitely use AlarmManager, because (from the docs):
The AlarmManager holds a CPU wake lock as long as the alarm receiver's onReceive() method is executing. This guarantees that the phone will not sleep until you have finished handling the broadcast. Once onReceive() returns, the AlarmManager releases this wake lock. This means that the phone will in some cases sleep as soon as your onReceive() method completes.
Although you don't need to fire any event while screen is off, AlarmManager still saves the battery by grouping alarms, when you use setInexactRepeating (but this is not important for you, because your interval is 10 minutes). And moreover, it can fire an event is app is not running. I vote for AlarmManager, because it's good practice, but considering your conditions, you can leave Timertask.
BTW, you can also use Handler, which I believe will be the best choice.
Our Application has a service which starts a timer to schedule a task every 4 hours.
But the phone often goes to sleep when the screen is off.
I don't expect the task to run when the phone is sleeping.
But I want that it can be run immediately if the phone has slept longer than 4 hours.
TimerTask task = new TimerTask()
{
#Override
public void run() {
//do something
}
};
new Timer().schedule(task, 0, 4*60*60*1000);//period=4 hours;
I have done some tests that show if then phone has slept for more than 4 hours and when it wakes up, the timer's period didn't add the past 5 sleep hours and it can't run the task immediately.
Its period time just calculates the phone's wake time.
I have studied Timer.java, and know the timer's delay mechanism is to use thread wait(), that is the reason.
How to make a cyclic time task that contains the phone sleep time?
I think there is no need to use an AlarmManager, because the task doesn't need to run when the phone is sleeping.
Thanks in advance.
Instead of using Timer, you need to use AlarmManager without the wakeup option set. If you do this the alarm will trigger the next time you wake up the phone after the 4 hours..
Check out this tutorial: http://www.techrepublic.com/blog/software-engineer/use-androids-alarmmanager-to-schedule-an-event/
So in my "Home" activity in my Android app, I have a non-deamon thread that is constantly running in the background that checks a blog for new posts every 30 minutes or so to fire notifications. It works fine when I make the thread sleep just for a few seconds for testing purposes to make sure that it is indeed working in the background, but in the actual phone, when the event is supposed to fire after half an hour, it just doesn't. So my question is, when I do *Thread.sleep(30_MINUTES)* does the android system kill it or something for being an inactive thread for too long? Does android kill sleepy threads?
Why don't you try AlarmManager to fire your polling code every 30 minutes ? Once the polling is done re-schedule if for the next 30 minutes. AlarmManager is much more reliable than making the threads to sleep
OK, so the problem was solved. What was causing the problem was that in Android when you put a Thread to sleep for let's say 30 minutes, when the device goes to sleep (the screen turns off after inactivity on the phone) the CPU goes into a so called "deep sleep state" which causes the thread's counter -that wakes the thread wake up- to pause while the screen is off. This means that when you say Thread.sleep(500000) for example, those 500000 milliseconds are counted only when the phone is awake. The solution is to use AlarmManager and a BroadcastReceiver to run the code periodically.
Here's a simple guide on how to use AlarmManager with a BroadcastReceiver: http://justcallmebrian.com/?p=129
I am not sure what you are doing in your coding but definitely android system does not kill a thread on its own whether sleepy or not doesnt matter.
What exactly is happening during this time? I believe the only situation in which what you're describing (using the technique you describe) would work reliably is if both (a) your activity (or another activity or service that runs in the same process) is the foreground activity for the entire life of the thread and (b) there's a wakelock preventing the CPU from sleeping.
Android may not kill individual threads, but it absolutely can and will kill processes based on the process lifecycle.