Am new to android. I am making an application which it will runs on AlarmManager I have searched many blogs.I got tutorials for activating the Alarm for few seconds,but in my case i wanted to activate an Alarm at a specific time in a day. Could you help me to do this?
Get the difference between the current time and the specific time of day in miliseconds, add it to System.currentTimeMillis() . Put this value in alarmManager.set(type, miliseconds, pendingIntent)
Related
I have a button that sets an Alarm using the AlarmManager.setRepeating and another button that removes it, every time an alarm is set the requestCode in the PendingIntent is iterated as to not confuse it with one that has already been set and canceled (the app will have multiple alarms set at the same time in the future). when i set the alarm (setRepeating) sometimes it works as intended sometimes it will fire off twice really quickly than at the time it was intended to go off 2-3 minutes later (i'm setting the alarm 3-5 minutes in the future for my test).
Also note: I have the device plugged in and the screen is set to stay a wake, during testing the app is usually always in foreground, sometimes i put it to background or rotate the screen (usually by mistake).
I have tried setExact() but i don't mind if its off by 0-5 minutes but i do need it to go off and not repeat.
i have played around with the initial time setting it to have started the day before at the hour and minute i want it to go off, same thing with ten days back and a hundred (just to see what would happen) similar results.
I am using Joda DateTime to get the milliseconds of the alarm time for the setRepeating method, and using AlarmManager.INTERVAL_DAY to set the intervals for the next alarm (my alarms need to go off every 24 hours)
requestCode is a constant int that i increment and track during testing.
context i get from getBaseContext() in the activity
My code to set the alarm:
Intent intent = new Intent(context, AlarmManagerBroadcastReceiver.class);
intent.putExtra(ALARMS_INDEX_KEY,requestCode);
PendingIntent sender = PendingIntent.getBroadcast(context, requestCode, intent, 0);
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);//After after 5 seconds
addAlarmIndex(context, requestCode);
//test: DateTime.now().minusDays(10).withTimeAtStartOfDay()
DateTime set_for = DateTime.now().withTimeAtStartOfDay().withHourOfDay(14).
withMinuteOfHour(34).withSecondOfMinute(0).
withMillisOfSecond(0);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, set_for.getMillis(), AlarmManager.INTERVAL_DAY , sender);
My code to cancel the alarm:
Intent intent = new Intent(context, AlarmManagerBroadcastReceiver.class);
PendingIntent sender = PendingIntent.getBroadcast(context, requestCode, intent, 0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(sender);
My code in AlarmManagerBroadcastReceiver extends BroadcastReceiver
#Override
public void onReceive(Context context, Intent intent) {
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "test_alarm:");
wl.acquire();
int alarm_index = -1;
if(intent.hasExtra(ALARMS_INDEX_KEY)){
alarm_index = intent.getIntExtra(ALARMS_INDEX_KEY,-1);
}
Log.i("medic_debug_timertest","Alarm !!!, fired #: "+DateTime.now().toString("YYYY/MM/dd # HH:mm:ss") + " alarm_index: " + requestCode);
wl.release();
}
What i'm expecting is the alarm gets set before the time it is meant to go off, than the alarm going off at the time it was set to go off at (withing several minutes of that time)
what happens is sometimes it dose not go off at all (perhaps I set the alarm to go off to close to when i am setting it) this may not be a problem but other times it goes off shortly after i set it and it will go off twice within 0-1 seconds apart that 1-2 minutes later it will go off again at the correct time it was set to go off at.
from what i observed so far it is always one of the three scenarios:
goes off at the correct time.
goes off not at all.
goes off three times, twice right away (1-2 minutes before the scheduled time) and than a third time at the correct time.
What am i doing wrong? how can I get the alarm to go off once at approximately the right time
UPDATE:
ok so... first of all I changed changed the line that sets up the timer from:
DateTime set_for = DateTime.now().minusDays(10).withTimeAtStartOfDay().withHourOfDay(14).
withMinuteOfHour(34).withSecondOfMinute(0).
withMillisOfSecond(0);
to
DateTime set_for = DateTime.now().plusMinutes(5).withSecondOfMinute(0).withMillisOfSecond(0);
so that it will go off exactly 5 minutes from when i set it and i can make multiple test without re running the app. I was concerned I was setting the alarm to close to when i set it up.
Something to remember is the AlarmManager bunches the alarms up and fires them at the same time if they are close together (with the setRepeating method not setExact), this is to save batteries and no wake the phone up every minute or two.
i did the test with the above code and it started to work more normally. set up 4 alarms 1 minute apart, 3 of them went off at the same tome when the 3rd one was supposed to go off (which is correct behavior because they get bunched up to one to save batteries) and the last one went off very late 3-5 minutes after it was supposed to (which is fine, no problem).
So perhaps the problem is after i canceled an alarm and start a new one the AlarmManager is getting confused (when i was setting the alarm before, to close to when i set it up) and trying to group the canceled one and the one that is supposed to go off and making the not canceled one go off twice? sounds odd but perhaps Alarm are somewhat bugged???
Ok Im not 100% sure why the alarm was triggering the same one three times, but when i give more time for the alarm to run (say 5 minutes in the future apposed to 3 minutes), giving it more time seemed to solve lot of problems. feeling a little silly now for not giving it more time in the first place but every test takes 5 minutes to run, lots of waiting, which is annoying but works better now.
in the post:
setRepeating() of AlarmManager repeats after 1 minute no matter what the time is set (5 seconds in this case, API 18+)
it is mentioned:
"As of I think Android 5.1 (API version 22) there is a minimum period of 1 minute for repeating alarms, and alarms cannot be set less than 5 seconds in the future"
I was definitely within that time(or not within that time rather, more that 5 seconds), but increasing the alarm set further in the future fixed my issue.
UPDATE: during testing I set my initial timer time to several days in the past, I have noticed that if it passed the interval even if the timer was not set than it will trigger a notification as several times as it passed those intervals from the time it was set from even if the alarm was not actually set at or before that time, so that's why i was getting those extra notifications, i assume there is a limit of 2 alarms (with the same requestCode) that it can go off like this.
I m creating a APP that works like a virtual time card: The user enter what time he enters at work, what time he goes out for lunch and what time he comes back at work again. Then he presses a button and he can see what time he can go out. Of course this is useful for whom, like me, have a flexible working hour.
The APP works. Now I'd like to add a new feature. Let's say I can exit my office at 5 PM, I'd like that my APP at 16:55 sent me a notification, an alarm. Something that reminds me that I can go out. How can do it ?
In my mind I have these steps:
I put in a variable the time I can go out from work
I check the current time and if it's five mins before the point 1 sends a notification
But, the program has to do this check everytime or once each minute at least. And I really don't know how to do it..
Can anyone helpe me out with an idea?
Ivano
Edit according to the rules and my new updates -
sorry my delay but I had to study what you sent me because I am a super rookie in Java... And i am really struggling trying to learn new things... Anyway let's get to the point. I tried to use the AlarmManager but It's not doing what I would like.
I added this code at the top of my MainActivity class:
AlarmManager alarmMgr = (AlarmManager)getSystemService(ALARM_SERVICE);
Intent intent = new Intent(this, OnAlarmReceive.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(),1*60*1000, pendingIntent);
What I get is that each 60 seconds the APP reloads itself, calls the MainActivity class and reloads the values the user entered previously into the DB. Therefore there is no way to enter a new value without see!!
What Id like is: The app stays in background "forever" and wakes itself up only when realises that in 5 minutes the user can leave the office.
I already wrote the part of the code where the program checks the current time and ask itself "does it lack 5 mins before the user can leave the office ? " and if the answer is yes, a text message appears and a sound is played. This is the part of the code :
NotificationCompat.Builder n = new NotificationCompat.Builder(this)
.setContentTitle("Arrivato nuovo messaggio!!")
.setContentText("Autore: Nicola Rossi")
.setSmallIcon(android.R.drawable.ic_dialog_info)
.setContentIntent(pendingIntent)
.setAutoCancel(true)
.setSound(sound);
So, the program works.. but has a minor glitch, where it only sends the notification out when I open the app 5-minutes before the end of my shift. If I open the app at any other time, it will not send out the notification. I want this notification to be sent out regardless of the time I open the app.
How can I fix it?
What you are looking for is called an alarm manager. This is a service outside your app you can use to notify the user. This service is called upon using pending intents.
https://developer.android.com/reference/android/app/AlarmManager.html
Ever played Candy Crush? Know how you run out of lives and have to wait 30 minutes to regenerate a new life and up to a maximum of 5? That is idea I am trying to implement in my app but I am uncertain on how to have code running even when the user closes app and/or phone.
My question is how to have a timer constantly running in the background of phone until the timer hits X minutes. Would I use the Timer class for this? Because I am familiar with that class and already have a form of it implemented in my app.
There are two pieces to your question:
To actually have a timer running so that you have an action taken after a certain period of time, use the AlarmManager. This should only be used if you are going to proactively interrupt or notify the user.
Your scenario doesn't actually need a timer, and it's more efficient not to use one unnecessarily. Instead, store a timestamp. When your app is opened again, compare the current time to the timestamp and calculate the effect. In the regenerating-lives example, you'd compare timestamps, see that 100 minutes have passed, divide by 30 minutes, and add 3 lives (maybe keeping the extra 10 minute remainder).
If you want timer to run in background you may use AlarmManager. You can set Alarm at specified intervals or you can set it in service if you want single shot alarms. Also while using AlarmManager beware that if your phone goes down then all alarms you've set will be vanished. So take care that you are saving alarm times before phone goes off. Take a look at:
http://developer.android.com/reference/android/app/AlarmManager.html
While using AlarmManager, use correct PendingIntent flags or you could lose previous alarms. If you still want more information you can raise here or have a google.
I don't think you can keep a timer running for you application even when the application is closed. Here is an idea i think about:
You need to start a timer when the life is gone and your application is running.
On your application close event, save that timer value in a persistent storage such as file
On appliction start, read the timer value from the persistent storage, and restart the timer for the remaining time
Once timer expires, generate a new life.
Hope it helps!
I found this answer that might be of great help. Hope it helps others.
There are several different approaches.
You can make use of the System's AlarmManager.
You can make your own Service.
You can make your TimerObject persist.
Check the link for the complete answer and links.
I am using AlarmManager to poll user location periodically which is working fine- Now I would like to give my app users an option so they can restrict the location polling by specifying hours say 'Between 8PM to 10PM'.
Right now I am using AlarmManager.setRepeating method for scheduling but I am unable to configure my alarm service so that it runs every day but within certain hours.
I already know how to schedule a recurring task using AlarmManager at particular time of day but how to set the end time is what I am looking for.
You can't tell AlarmManager to do exactly that, but you could check whenever your service gets called to see if it's within the specified hours. If it is, then you proceed as normal, if not then you reschedule the alarm to start at the beginning of the next polling period.
i want my app to run in the background as it has to get the time every second..and do some task when the user sets a time and wants the app to do some task at that time..!!
Have you considered using the AlarmManager?
Android provides an AlarmManager
service that will let you specify an
Intent to send at a designated time.
This intent is typically used to start
an application at a preset time.
(Note: If you want to send a
notification to a sleeping or running
application, use Handler instead.)
If you do something every second, it us unlikely the user's device will reach the 24 part without being plugged in to power.
Android apparently already contains a scheduling service so you don't need to create your own.
Does this article help. Don't forget to follow up the links provided in that article.
I agree with every single person in this thread! AlarmManagers are your best friends when it comes to executing services at a certain interval. They are very easy to set up too, here's a very simple example of a repeating alarm:
//Get the alarm service
AlarmManager alarm = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
//Create the intents to launch the service again
Intent new_intent = new Intent(<The intent to set off>);
PendingIntent p_intent = PendingIntent.getBroadcast(this, 0, new_intent, 0);
//Create a repeating alarm
alarm.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, <Time in milliseconds to set off first alarm>, <How long between each alarm in milliseconds>, p_intent);
Note that I'm using an inexact alarm to set of the alarm so it doesn't try to interrupt any other important services. It is possible to use an exact alarm but if your execution isn't really that important I highly suggest inexact alarms. You can find a lot more info below:
http://developer.android.com/reference/android/app/AlarmManager.html