I am not sure how to describe my Problem. Basically I want to write an app, which reminds the user after a specific time (e.g. 1hr) of something. Unless he does not confirm the reminder, it will nag him every 10 mins, after the initial hour has passed.
Until the reminder pops up for the first time there will be 4 stages (eg. every 15mins), which should be shown inside the activity (eg with colors green, yellow, orange, red).
I implemented the reminder with a Broadcast Reciever and the AlarmManager, so far so good. But how can I check how long its been since the Alarm was set to find out in which stage I am? If the Activity is running in the foreground while the stage changes, the change should be made visible instantly. If the activity is started while the alarm is still counting down, the current stage should also be shown.
Anyone can point me in the right direction on how to do this in a good way, since I am still fairly new to Android.
Thank you.
[So far I basically followed this tut http://www.vogella.de/articles/AndroidServices/article.html]
You may want to maintain an int that represents the state of your counter. You can make it a member variable in your Activity, and you may want to persist it in shared preferences as well. To pass status change notifications from the alarm service back to your Activity, send an Intent. Your activity need not check up on the alarm counter; it can simply wait for the intents to roll in.
Related
I have an App where the user can create multiple countdown alarms. Each one has it's own name, time to count, ringtone, etc.
I extended the CountDownTimer to hold each alarm setup and created a Singleton manager to manage all the alarms.
Everything is working fine until I leave the App.
The counters don't actually die. They have a weird behavior. After starting a counter:
1) if I press back key until the home screen and then power off the screen the alarm will trigger as it should.
2) if I press the home button then turn off the screen it will trigger only if I open the app.
3) if I just turn off the screen while still on the app it will trigger as soon as I turn on the screen.
I expected trouble because for that kind of thing I need to use Services, Handlers or other stuff like these.
The problem is, I'm new to Android and after reading a lot about it, I couldn't find a solution.
As far as I understood I should use Services, but it can have only one instance. How would I work with multiple alarms?
Is there other way of doing it?
I need a way to start each alarm and tell the system to keep counting no matter what happens! (and to call an Activity when it finishes)
Any help?
Is there other way of doing it?
If your goal is to alert the user of events in the future, regardless of whether your app is running, dump all your CountdownTimer logic, and switch to AlarmManager. It is specifically designed for this sort of scenario. You can set up an AlarmManager event for each timer, to get control when the end time is reached.
Also note that you will need to maintain information about your registered events in a file or database:
so users can add and remove them, and
so you can set up AlarmManager again if the user reboots their device
and to call an Activity when it finishes
Users may reject your app for that behavior. Not everyone wants to be interrupted in the middle of what they are doing with their device. Please allow this to be configurable, so the user can opt for something less intrusive, like a Notification.
You should replace your CountdownTimers with AlarmManager (as in CommonsWare's answer), after setting it up it will trigger your function to execute on specified time, here is official guide:
http://developer.android.com/training/scheduling/alarms.html
Soon you will find that after device reboot your alarms are lost, you need to restart them by catching android.intent.action.BOOT_COMPLETED broadcast.
Also you should not do a lot of work in your alarm onReceive, you should pass information to some other component like IntentService, to make it safe while device is asleep you should use WakeLock (sample project).
[edit] ---- you should also store your alarm/ringtone related data in some persistant storage, you can use for it shared preferences, or (more work) sqlite database.
I you really want to use timer (i.e. when you want to show countdowns on screen):
You don't have to have multiple timers to show multiple countdowns.
Everything you have to do is just put the target time into some collection, or event put it into the View.setTag().
Then you have timer (let say 1s tick) - on every single tick you have to iterate over all your gauges, check the target time and current time, parse the number and adjust the gauge.
However - as the timers works on separate (non main) threads - you will have to use handler or something like that.
If you want to just set some alarms - take the CommonsWare's answer - it's good one.
I've read and re-read the documentation but I'm still now sure if using a service (and how) is the right way to keep a timer running.
I basically want to have a countdown timer, but I want it to run uninterrupted even if the app gets closed (and show up as an ongoing notification). When a certain activity in the app gets opened (resumed, opened, launched from clicking on the notification), I want it to be able to get the current value from the timer (no more frequent than once per second). If the app got closed, I still want the timer to be able to use/launch activities or other services (or access the database) of my app.
So if I understood the Android developer docs correctly, I should use a service that is started (because when started it should be able to do its thing even in the app gets closed) and bound (so an activity can get data from it). Then I searched Stack Overflow for similar topics and some people are recommending using IntentService (but can it send data to an activity?), or Handlers or even AlarmManager.
I'm really confused and I'd prefer to be able to pick the right approach from the start (rather than finish the app and then realize my approach wastes a lot of battery or something). The problem with documentation is it answers questions it thinks I have, so I have to ask a real person.
My suggestion is:
When user starts your timer save current system timestamp.
In your UI: Every N milliseconds just read saved value and compare it to current timestamp. This give you a diff = elapsed time.
You do not need any timer/service/alarm manager. Every time user has return to your app you just do step №2 to show elapsed time.
How to check the current device time in background at regular intervals(say every 1 hour) even after the app is closed using startService() method?Thanks
You don't necessarily need a service, depending on what you want to do with the time you get.
As a general rule, to do something at regular intervals you can use AlarmManager.setInexactRepeating() (or setRepeeating() if you really need a perfect periodicity). Use the PendingIntent of this method to start whatever (BroadcastReceiver, Activity, Service...) when the alarm is triggered.
Basically I'm working on an application that alerts drivers how long they have been driving. It requires alerts at certain times.
At the moment I'm using a chronometer that displays time passed.
As one hour passes I need a message to appear on screen saying 'Hour Passed'.
As 2 hours passes I need another message saying 'Hour Passed' and a further message saying 'A 15 minute break is required'. Then a button needs to appear that allows the user to start a break which until starts a new chronometer.
When the break is complete at 15 minutes, a button needs to appear that says 'continue driving' and the original chronometer displaying driving time needs to continue from the time it was at before the break (2:00:01).
As you can see all the functionality is relatively similar, based on time events.
I'm guessing I need to use some sort of if statements that are initiated when the chronometer reaches a certain time but I'm basically stuck on how to make the application do the required functionality when the chronometer reaches a certain time.
Try taking a look at the AlarmManager class to run an intent a certain amount of time after the time the stopwatch is started.
Try using the alarm manager with a pending intent.Create a receiver that catches the pending intent action and do whatever you want to do.
You can either register a broadcastreceiver from your app when it is started(preferred way in your case) or create a broadcastrecievr and create a intent filter in the manifest file...In this case the event would be catched even if your app is not running.
I'm currently developing an android application that will repeatedly ask a question to the user in randomly determined time intervals. This means it will wake up the device if nessecary, pop up an Activity, make a sound or vibration and let the user choose one of the options.
The user will be able to turn the series of pop ups on or off. The user will also be able to temporarily turn it off for a self-determined period of time. Lastly the user will be able to specify designated times of the day in which the series of pop ups will turn on or off automatically.
I already know how to schedule Activities and BroadcastReceivers with AlarmManager. I also know how to wake the device up by looking at the source code for the alarm clock on android.
My question is how to best implement it with the Android framework. When the pop up series start my application needs to randomly determine in which interval the next pop up will occur. When the time has come for the notification to be displayed. The Activity will pop up (already implemented) and immedeately the next pop up time will be randomly calculated. When the user has not answered the question in the pop up when it is already time for the next pop up, the application must know that. The application must also be able to determine when is has to start and stop its pop ups as specified by the user. At all these points something must be called.
I'm wondering if I could best do all this with a BroadcastReceiver receiving a series of different actions by Intent. Or should I use a Service doing all the work. And if I use a service is it best to send it different commands through onStartCommand() or should I rather bind to it and call the methods through the Binder?
I found the source for the alarm clock rather confusing on this matter and I'm unsure which method is the best. They all seem to have their strong and weak points.
Services can have 'states', but the system may decide to destroy it to free memory, thus losing this data. Scheduled BroadcastReceivers will be remembered by the AlarmManager, but they are 'stateless'.
With bound Services you can communicate both ways, but it takes some time to accuire the Binder. Started services can be given quick commands through onStartCommand(), but cannot directly communicate with Activities.
The decision remains hard...
The decision remains hard...
There is only one answer: use AlarmManager with a BroadcastReceiver. Nothing else can reliably wake up the phone. That BroadcastReceiver, in turn, should acquire a WakeLock and start up your activity. The activity can use android:keepScreenOn to keep the device awake while the activity is in the foreground; the activity should release the WakeLock acquired by the BroadcastReceiver in onCreate() after the call to setContentView(). The activity can schedule the next alarm based upon user input or lack thereof.