Pretty new to android, so forgive me if this is a dumb question...
So, I'm making an app with a countdown timer that will ring periodically, and then again when the countdown hits zero - simple enough. However, I want the app to keep running even when the user closes the application or the phone is asleep, so that whenever the timer rings, the app will wake up and display an activity showing the time until the countdown is finished. To do this, I'll need to use a service, and lo and behold, the google devs made the AlarmManager service just for me! Sweet!
However, I noticed 2 things:
1) the AlarmManager class has no default constructor, so I'm assuming I can't just extend it and tack some logic on so that I can get all this done in one shot. Ok, cool - I'll just make a service that instantiates AlarmManager at the start, and implement my logic there.
2) In the documentation, I don't see any way of getting either the elapsed time or the remaining time from AlarmManager once it is running.
So, my question is: does this mean that I will need two timers that I start at the same time? Say, an AlarmManager to wake the phone up and call the activity, and a CountDownTimer contained in the service to hold the remaining time and call the alarm ringtone?
Thanks for helping out my clueless ass.
You could extend AlarmManager. However the common way is to get an instance of it, which is running as a system service.
Get the instance using Context.getSystemService(Context.ALARM_SERVICE) and you will be able to register your PendingIntent to that system service, which is independent to your own app. The PendingIntent can either start an activity or send broadcast with some Intent. You don't monitor the elapsed time constantly in AlarmManager. Rather, you calculate the time difference between the current time of your method call, and the desired time to fire your event. And then you set an alarm in AlarmManager with a PendingIntent representing the action you wish to take at that interval, or a time point.
On the other hand, if you want maximum flexibility, run your service as foreground service and listen for system broadcast like ACTION_TIME_TICK, which is fired every minute. Alternatively if you don't run service in foreground you could also run your service with START_STICKY, which guarantees that your service will be restarted after the system kills it (due to sleep or closing app). Think this as a background service that is constantly running. This provides you a lot of flexibility in your implementation.
Related
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.
I have an app that uses a CountDownTimer inside a BraodcastReceiver. The CountDownTimer can be for upwards of 1 hour. The timer shows the countdown in the Notifications area (second intervals).
Some users have reported that the app seems to hang on long count downs. The CountDownTimer is triggered by a widget.
Does anyone know if a CountDownTimer can be stopped and reclaimed by the OS?
The alternative would be to set a recurring alarm at 1 second intervals which runs a service. Is there a better option?
Does anyone know if a CountDownTimer can be stopped and reclaimed by the OS?
Your process will be.
The alternative would be to set a recurring alarm at 1 second intervals which runs a service.
That's not an option in any practical sense, if by "recurring alarm" you mean AlarmManager. AlarmManager is not designed for every-second events.
Is there a better option?
This is one of the few cases that justifies a foreground service. Since you have a Notification anyway, and since your AlarmManager approach would keep the service around constantly anyway, you may as well dispense with the AlarmManager and use startForeground() to keep the service around. Update the Notification that you are using with startForeground(), and use ScheduledExecutorService to get control every second on a background thread.
When the countdown is done, call stopForeground() and stopSelf() to get rid of it all.
I am making an app that needs to execute a function each hour even the app is closed.
First of all, I thought to create a service, but during my tests, I realise that android sometimes kills my service. So I was looking for another solution and I found AlarmManager. I have implemented it and it seems to work but I have the doubt if it will happen the same the service or it will run forever? (Until reboot of the mobile...)
Another question, it is necessary to create a new thread to execute the process in alarm manager or it runs directly in other thread?
I have implemented it and it seems to work but I have the doubt if it will happen the same the service or it will run forever? (Until reboot of the mobile...)
It will run until:
the device is rebooted, as you noted, or
the user uninstalls your app, or
you cancel the events yourself, or
the user goes into Settings, finds your app in the list of installed apps, taps on that entry, and clicks the Force Stop button
It's possible that alarms will need to be scheduled again after your app is upgraded (I forget...).
it is necessary to create a new thread to execute the process in alarm manager or it runs directly in other thread??
Unless the work you are going to do will take only a couple of milliseconds, you will want a background thread for it. That leads to two possible patterns:
If you are not using a _WAKEUP-style alarm, use a getService() PendingIntent to send control to an IntentService every hour
If you are using a _WAKEUP-style alarm, you will need to use a getBroadcast() PendingIntent, and have it either invoke your subclass of my WakefulIntentService, or you will need to manage a WakeLock yourself to keep the device awake while you do your bit of work
No, Android won't kill scheduled alarms and they got executed as planned unless app is replaced or device is rebooted. Use broadcast receivers for these events to reschedule Alarms. There's no way to prevent Force Stop as it kills all of your app components and threads totally.
That depends on what Alarm Manager do. If it sends a broadcast, the receiver limit is 10 second.
If it starts an Activity, Service or Intent Service, there is no limit. For Activity and Services you must finish or stop it and for Intent Services until the process is finished. Be aware that you can't have another thread inside Intent Service and you'r limited to code inside the OnHandleIntent.
Also you must consider device state. If it's sleep and you are using Wake Up flag receivers won't need a wake lock, but others do. It won't take long for device to go back to sleep.
Don't waste system resources with a service because Alarm Manager do what you want.
I have two examples of Intentservice. One is the Download example in the commonsware book. the other is at http://www.vogella.com/articles/AndroidServices/article.html#servicecommunication_handler.
Both of these examples show the service executing a finite task and they both apparently destroy themselves by running to the end of the scope of the onHandleIntent event.
The service I am writing has to have events and listen for things. One is a LocationListener listening for GPS movement. Another makes Posts to a REST service and listens for replys. I want it to run until a time has elapsed or until it was told to quit by the activity that started it.
How do I keep it running? Where, for instance, do I put my implementation of LocationListener?
Thanks, Gary
How do I keep it running?
You don't. IntentService is designed to do a piece of work (or perhaps a few off a queue, if commands happen to come in rapidly), then shut down.
The service I am writing has to have events and listen for things.
Then you should not be using an IntentService. Use a regular Service, with your own background thread(s) as needed.
To keep a service running, your service need to return START_STICKY in the service method onStartCommand().
With this, the service will be running even if you exit form your activity.
Note:
The Android still kills services after some time (30 mintus to 1 hour) if they are not foreground services. Use startForeground(notification) to make it foreground.
good luck
You can achieve this in either of two ways,
AlarmManager
TimerTask
AlarmManager is android's in-buite class that allows you to execute certain action on particular time peroid.
TimerTask does same thing as AlarmManager, you can repeat certain action of your code again and again.
However AlarmManager is ligher in the execution so i suggest you to go with AlarmManager class.
Create an AlarmManager that fetches the GPS Co-ordinates and post them to server on regular interval basis.
Have a look at to this AlarmManager Example.
First time I have tried to implement either of these and I am unsure which to use.
I want my application to create a time frame, e.g. 2/3/12 to 7/3/12. Multiple time frames such as this can be created. A different intervals (e.g. every 4 hours) I would like my application to preform some actions for each time frame. This needs to be done in the background.
I have first tried to implement this with a Service, but am having performing all the actions for each of the time frames concurrently. After reading the android blog "Multitasking the android way" I think that perhaps BroadcastReceivers are better.
Please advise
Please see my answer about using the AlarmManager - Running task periodicaly(once a day/once a week)
If you are only running a process at a set time rather than constantly (e.g. monitoring audio levels) then you are going to ask a service to sit there 90% of the time and do nothing except waste battery power. The AlarmManager solves this problem as it notifies the broadcast receiver to execute at the given times.
Edit: Also bear in mind that after phone restart all alarms are removed so you will need to register a broadcast receiver to be notified of the device boot-up so you can re-register any Alarms that are needed.
You should probably be using the AlarmManager and a IntentService.
The AlarmManager will kick of your IntentService at specified intervals. You can kick off the IntentService for each set of actions.