Re-enabling the Android Alarm - android

I am having one alarm that can be created by the user and can be disabled by the user.
When user disables the alarm, I simply cancel the alarm using AlarmManager and store the alarm time somewhere.
Now, when the user re-enable the alarm, I create the alarm and set the stored time in alarm. The problem is that when I recreate the alarm with the stored time, the onReceive() method of alarm broadcast getting called instantly.
I am setting the alarm as below:
alarmManager.setRepeating(AlarmManager.RTC, time, AlarmManager.INTERVAL_DAY,
PendingIntent.getBroadcast(
this, alarmUniqueCode, intentAlarm, PendingIntent.FLAG_UPDATE_CURRENT));
How I disable the alarm when the user clicks on disable:
sender = PendingIntent.getBroadcast(this, 1, intent, 0);
alarmManager.cancel(sender);
I have added the alarm receiver in manifest file like below:
<receiver
android:name="com.sign.android.myscheduler.app.AlarmReceiver"
android:enabled="true"
android:exported="true" >
</receiver>
One more question: When I disable the alarm, I call cancel method. Should I need to unregister the broadcast receiver too? If yes, then what if I have two different alarms then? How can I unregister the broadcast receiver for only one alarm?

For your problem, the alarm will be triggered immediately if you set the time in the past
From AlarmManager API documentation:
If the stated trigger time is in the past, the alarm will be triggered
immediately, with an alarm count depending on how far in the past the
trigger time is relative to the repeat interval.
In this case, you have to check first whether the stored time is in the past. If yes, then you have to add intervals until the time is in the future.
Try changing the code to:
long now = new Date().getTime();
while (time < now) {
time += AlarmManager.INTERVAL_DAY;
}
alarmManager.setRepeating(AlarmManager.RTC, time,
AlarmManager.INTERVAL_DAY, PendingIntent.getBroadcast(this,
alarmUniqueCode, intentAlarm, PendingIntent.FLAG_UPDATE_CURRENT));
Regarding your second question, I cannot really answer. However, based on my self-experience, I don't have any problems even if I leave the receiver on.

Related

Launching custom Activity when alarm goes off in custom alarm clock app Android

I know there is a lot of discussion about AlarmClock and AlarmManager and how to set alarms, launch apps, etc. However, I am yet to find the perfect answer for the following scenario.
In my Android alarm clock application I'm developing, I want to set an alarm for a specific time, pass in other settings such as what song to play, vibrate, etc.
1) what should I use to do this? AlarmClock or AlarmManager?
2) Now, when the alarm goes off at the specified time, how do I tell it to launch my custom Activity? Again the question of AlarmClock or AlarmManager.
This custom activity would show the time and have buttons saying "Sleep" or "Snooze" which the user can press (pretty much what happens when an alarm in any other alarm clock app goes off). I don't want to launch my alarm app, ONLY that one screen when the alarm goes off. When the user hits a button, I want to close that custom acitvity and for nothing else related to that app to open. I would like it so that the user can go back to doing whatever they were doing.
I think you can do your job with AlarmManager. As you say, if you want to set alarm for a specific time, you should use setRepeating(). If you want to wake up your device when the alarm fires choose RTC_WAKEUP type and if you don't want that RTC type. You define a PendingIntent, whatever you want to do(play sound, light and vibrate), you can do within this activity that attached to this intent. You should design your layout in that(YOUR_ACTIVITY) layout and put buttons to snooze/cancel alarm.
private AlarmManager alarmMgr;
private PendingIntent alarmIntent;
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 14);
alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, YOUR_ACTIVITY.class);
alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, alarmIntent);
Above code set an alarm for 14:00 and interval of one day which means it will be fired everyday 14:00 and run YOUR_ACTIVITY until you cancel it. this is an example in Google Android Documents.

Alarm SET OFF AND ON in Android

I am creating a clock application that has alarm feature too. The time is showing up properly and I am also setting multiple alarm properly.
I am creating multiple alarm using different id and also saving the same into Database so that I can view the list of alarms in a listview. Now I am trying to set ON and OFF functionality for my alarm. I have a problem there.
On itemclick if alarm is ON it switches OFF with the help of:
Intent intent = new Intent(Main.this,TaskRecieverForAlarm.class);
PendingIntent pi = PendingIntent.getBroadcast(Main.this, Integer.parseInt(cont[0]), intent, 0);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.cancel(pi);
The above code cancels the alarms perfectly fine.
To switch ON the alarm I am using:
Intent intent = new Intent(Main.this, TaskRecieverForAlarm.class);
intent.putExtra("AlarmDate", cont[1]);
intent.putExtra("key", Integer.parseInt(cont[0]));
PendingIntent sender = PendingIntent.getBroadcast(Main.this, Integer.parseInt(cont[0]) , intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
if(type.equalsIgnoreCase("daily"))
{
am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), sender);
am.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 1440*60000 ,sender);
}
else if(type.equalsIgnoreCase("weekly"))
{
am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), sender); am.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 7*1440*60000 ,sender);
}
Now as soon as I click the OFF to ON, alarm triggers and calls the TASKReceiverFORAlarm (broadcast receiver) even though the alarm time is 4 or 5 hours from the current time. I am not sure where I am going wrong?
Can somebody help me out?
Thanks!
I think I found the answer here:
public void setRepeating (int type, long triggerAtMillis, long intervalMillis, PendingIntent operation)
Added in API level 1
Schedule a repeating alarm. Note: for timing operations (ticks, timeouts, etc) it is easier and much more efficient to use Handler. If there is already an alarm scheduled for the same IntentSender, it will first be canceled.
Like set(int, long, PendingIntent), except you can also supply a rate at which the alarm will repeat. This alarm continues repeating until explicitly removed with cancel(PendingIntent). If the time occurs in the past, the alarm will be triggered immediately, with an alarm count depending on how far in the past the trigger time is relative to the repeat interval.
If an alarm is delayed (by system sleep, for example, for non _WAKEUP alarm types), a skipped repeat will be delivered as soon as possible. After that, future alarms will be delivered according to the original schedule; they do not drift over time. For example, if you have set a recurring alarm for the top of every hour but the phone was asleep from 7:45 until 8:45, an alarm will be sent as soon as the phone awakens, then the next alarm will be sent at 9:00.
If your application wants to allow the delivery times to drift in order to guarantee that at least a certain time interval always elapses between alarms, then the approach to take is to use one-time alarms, scheduling the next one yourself when handling each alarm delivery.
Parameters
type One of ELAPSED_REALTIME, ELAPSED_REALTIME_WAKEUP}, RTC or RTC_WAKEUP.
triggerAtMillis time in milliseconds that the alarm should first go off, using the appropriate clock (depending on the alarm type).
intervalMillis interval in milliseconds between subsequent repeats of the alarm.
operation Action to perform when the alarm goes off; typically comes from IntentSender.getBroadcast().
The way you use that function is:
am.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 1440*60000 ,sender);
Try this one:
//The only variable here is the desired hour of the alarm, which
// has to be obtained in milliseconds
long alarmSetAt = // The hour of the Alarm for the current date in milliseconds
long time = cal.getTimeInMillis() - alarmSetAt;
if(time > 0){
time = -time + cal.getTimeInMillis();
}
else{
time = time + cal.getTimeInMillis() + 1440*60000;
}
am.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 1440*60000 ,sender);

Alarm Manager events not fired (registering for notifications per day)

I am writing an application which needs a homewidget showing the current date. For that I have used the alarm manager registering as follows:-
Intent intent = new Intent(HomeScreenWidgetProvider.ACTION_UPDATE_DATE);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetId);
intent.setData(getUriData(appWidgetId));
PendingIntent datePendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarms = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
alarms.cancel(datePendingIntent);
**alarms.setRepeating(AlarmManager.RTC, getTimeForMidnight(), AlarmManager.INTERVAL_DAY, datePendingIntent);**
As you see, the above code registers for notifications first for the next 12.00AM with an interval of a day from there on. I update the date in my widget when I get a notification from alarm manager.
There is one big problem though. I don't get the alarm manager events when the date changes (at 12.00AM). And so the date does not change in my home screen widget.
The above code works fine in the emulator but not on the device. I am using Samsung Galaxy S 19000 for (real time) testing.
Is there a problem with use of alarm manager? Or is there an alternate way of receiving date change notifications?
I think in setRepeating() method, you should set the first parameter as AlarmManager.RTC_WAKEUP. If you use AlarmManager.RTC, the alarm event won't be triggered when the device is asleep. Please see the SDK document about AlarmManager for more details.
Also, you can register a BroadcastReciever listening to ACTION_DATE_CHANGED, by which you can receive date change event.
Hope it helps.

Android Notification repeatation

I want to set notification for an event which will repeat every day. So the notification should come everyday at event time. How to set any notification in NotificationManager so that it repeats after certain period of time.
If you are using AlarmManager class, it's more easier that to setup a service.
alarmManager class has a setRepeating method that repeats your alarm call at given interval after given time.
Like..
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
Intent AlarmIntent = new Intent(CONTEXT, RECEIVERCLASS.class);
ID,AlarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,YOURCALENDAR.getTimeInMillis(), AlarmManager.INTERVAL_DAY, Sender);
In the setRepeating argument, you can set the YOURCALENDAR member to the time you want......
You kinda need a Service
for this, if I got your question right
for this u have 2 made one service class that notify your event.
when any event occurs just call start notification on event. if u not get proper idea that comment on this ans. i'll explain in detail.

Android repeating alarm not working

This works fine:
Intent intent = new Intent(HelloAndroid2.this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(HelloAndroid2.this, 0,
intent, PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (12 * 1000), pendingIntent);
This doesn't work. I hear the alarm only time.
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (12 * 1000), 3 * 1000, pendingIntent);
I have also tried this, no luck:
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 5);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 7000, pendingIntent);
What is the problem?
From the PendingIntent doc for FLAG_ONE_SHOT:
this PendingIntent can
only be used once. If set, after
send() is called on it, it will be
automatically canceled for you and any
future attempt to send through it will
fail.
So after the pendingIntent is fired the first time, it will be cancelled and the next attempt to send it via the alarm manager will fail
Try using FLAG_UPDATE_CURRENT
Looking at your code samples in order:
In your first sample you are using AlarmManager.set - this is strictly for one-off alarms so yes, it will only fire once. If you want to use AlarmManager.set then the last thing the code triggered should do is to set a fresh alarm (which should also use a fresh PendingIntent).
In your second example you are using a repeating alarm. You do not need to create a fresh PendingIntent each time this fires as the OS takes care of the repeating aspect of the alarm.
There is no reason why your alarm should not repeat every 3 seconds, so I would start looking at the BroadcastReceiver implementation you have written to handle the alarm.
Check that you've implemented it properly. Comment out all the code in the onReceive() method and instead just have it writing a log message. Once you see your log message appearing in the logcat every time the alarm fires, add your code back in (keeping the log message), and another log message to the end of the method. This allows you to see how long the method takes to execute - you want it to be finished before the alarm fires again to avoid any unexpected side effects.
As an aside, if you want a repeating alarm, android.os.Handler is a much more efficient approach although alarms set through AlarmManager do fire very accurately.

Categories

Resources