Android Dev: AlarmManager Reschedule and Service - android

please refer to
this for the issue i was facing....as suggested by the person who replied to my problem + what my additional research showed is that i need to use AlarmManager to solve my sleep & timertask issue...since, i have started changing the existing code to utilize PendingIntent along with AlarmManager with: Thread thr = new Thread(null, mTask, "ServiceName"); in the service...
after reading the AlarmManager documentation several times, i dont know how to reschedule a AlarmManager... im working on a Profile Switcher application, which will various run intervals (like i described in my problem thread)...
Does anyone have any suggestion?

i dont know how to reschedule a AlarmManager
Use cancel() to remove an existing alarm, and use set() or any of the other set...() methods to schedule alarms. To "reschedule" alarms, you cancel the old and create the new.

If you use the same intentString and the same request code, your alarms will be overwritten.
In your intent, you can use the following flag:
PendingIntent.FLAG_UPDATE_CURRENT
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, notification.getId(), new Intent(intentString), PendingIntent.FLAG_UPDATE_CURRENT);
long startDateTimeMillis = notification.getDateTime().toDateTime().getMillis();
MyApplication.alarmManager().setExact(AlarmManager.RTC_WAKEUP,
startDateTimeMillis,
pendingIntent);
Related to the alarm itself, you can use the methods setExact() or set() and you can search about them to check which one fits you better.

Related

Can AlarmManager schedule more than one alarm from the same code?

If I allow my user to schedule a notification using AlarmManager, and then they schedule another notification using the same code, will the first alarm be overridden? Or will both alarms be set?
When creating a pendingIntent you have to include an id:
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, ID , intent, Flags)
If the number in the ID location is always the same, then the alarm will be overridden. If it is the same then it will not be.
You can use the same code, as long as the ID is different. You can achieve this in many ways, like creating an ID based on the time you schedule the alarm for, as you may not need two alarms for the same time.

Android - Alarms sometimes fires at the wrong time using AlarmManager

This problem seems a little bit odd, but if someone as encounter something like this, please help me...
I created an Alarm Scheduler, that sends an alarm to the user using AlarmManager, through this code:
Intent intent = new Intent(context, AlarmReceiver.class);
intent.putExtra("tk_alert_id", lastAlertId.getId()+"");
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, idRandom, intent, Intent.FLAG_ACTIVITY_NEW_TASK);
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, date.getTimeInMillis(), pendingIntent);
The problem is that, sometimes, I receive this alarm on my AlarmReceiver (BroadcastReceiver) at a wrong time, as you can see in the image bellow:
image, and I can't figure out what's the problem... I checked the time for date and was set as "2015-05-27 17:00:00", but it was received a little minutes earlier (around 16:57) ...
Does anyone knows what kind of problem I am encountering here?
For API levels <19 you should use AlarmManager.setRepeating() and your alarms will trigger exactly at specified time.
Api levels >=19 and above this no longer works. There was change in android so that all repeating alarms are inexact.
So if you would like to achieve exact repeating alarm use AlarmManager.setExact().
See this question for more info.
Edit
For your purpose (a one-off alarm, at a precise time) use alarmManager.setExact(....). See docs

Android - How to reschedule alarms associated to app events

I found a lot of examples and questions regarding how to fire an alarm using AlarmManager (both periodical or single), but nothing similar to what I need.
My user can schedule a certain number of events (i.e. things to do), with a single-shot alarm for each of them to be fired one day before the scheduled start (showing a notification). This is easy.
My problem is that this scheduled start can be changed, thus the alarm should be moved too.
I was thinking to delete the old alarm, and to create a new one considering the new scheduled start. Knowing that I can delete an alarm using alarmMgr.cancel(alarmIntent), how can I delete the specific alarm related to the rescheduling event? Should I make each alarmIntent unique in some way?
Or there is a better way that I didn't consider (except using Google Calendar APIs to schedule and reschedule an event there, and making it managing the notification)?
While scheduling an alarm using set() API
public void set (int type, long triggerAtMillis, PendingIntent operation)
in the last argument you can mention a request code using getBroadcast
public static PendingIntent getBroadcast (Context context, int requestCode, Intent intent, int flags)
an example for this would be :
alarm.set(AlarmManager.RTC_WAKEUP, time, PendingIntent.getBroadcast(mContext, id, intentAlarm, PendingIntent.FLAG_UPDATE_CURRENT));
When you want to cancel or reschedule you can use the 'id' to specify which alarm.

Android Alarm Clock - Remove alarms programmatically

I am writing an application in which user can configure alerts/alarms. At this point, I have everything working expect the one. I am firing off an alarm using
Intent alarmIntent = new Intent(AlarmClock.ACTION_SET_ALARM);
alarmIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
alarmIntent.putExtra(AlarmClock.EXTRA_MESSAGE, "Some message!");
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.MINUTE, 1);
alarmIntent.putExtra(AlarmClock.EXTRA_HOUR, calendar.get(Calendar.HOUR_OF_DAY));
alarmIntent.putExtra(AlarmClock.EXTRA_MINUTES, calendar.get(Calendar.MINUTE));
alarmIntent.putExtra(AlarmClock.EXTRA_SKIP_UI, true);
context.startActivity(alarmIntent);
I want to remove this alarm once user has dismissed using the Dismiss button. I can see the alarms being still there in the alarm clock which I set using above code through my application.
Is there some way to get a cursor or something similar on the alarms being there in the alarm clock? This will help me iterate over them and remove the ones I want.
Any help would be appreciated, Thanks in advance.
As it was answered here: there is no supported API to this.
Official documentation says that
If a time of day is specified, and EXTRA_SKIP_UI is true, and the
alarm is not repeating, the implementation should remove this alarm
after it has been dismissed.
But different manufactures implement their own alarm clocks and I'm not sure if someone supporrts this.
I have tried it on JB emulator and looks like it dosen't work. Maybe, on KitKat?
Only this one is ok on JB:
If an identical alarm exists matching all parameters, the implementation
may re-use it instead of creating a new one
So, maybe, better solution is to use youre own alarm, created with AlarmManager or warn user that he has to remove Alarms by hands (to make it more obvious - not use AlarmClock.EXTRA_SKIP_UI).
call method cancel(...) from AlarmManager, using the same PendingIntent you used to set the alarm. Example:
mAlarmPendingIntent = PendingIntent.getActivity(this, requestCode, intent, flags);
this.getAlarmManager().cancel(mAlarmPendingIntent);
this refers to the Activity or the Service from which you are cancelling the alarm

pendingAlarmIntent.cancel() or AlarmManager.cancel(pendingAlarmIntent)?

I'm just looking at how to cancel an alarm and I came across these two methods. Which one should be used in what situation and why? Are they both the same?
I am currently doing this:
Intent alarmIntent = new Intent(ChangeAlarmActivity.this, AlarmReceiver.class);
PendingIntent pendingAlarmIntent = PendingIntent.getBroadcast(ChangeAlarmActivity.this, (int)alarm.getID(),
alarmIntent, 0);
pendingAlarmIntent.cancel();
How is that different to this below?
Intent alarmIntent = new Intent(ChangeAlarmActivity.this, AlarmReceiver.class);
PendingIntent pendingAlarmIntent = PendingIntent.getBroadcast(ChangeAlarmActivity.this, (int)alarm.getID(),
alarmIntent, 0);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
alarmManager.cancel(pendingAlarmIntent);
Are they both the same?
No.
If you want to cancel an alarm, call cancel() on AlarmManager.
cancel() on PendingIntent probably will appear to have the same effect -- whatever your alarm events were supposed to trigger no longer happens. However, you are then assuming that AlarmManager will detect this and clean things up on its side, which is not guaranteed. Particularly for _WAKEUP alarms, this could result in the device being woken up for no good reason, wasting battery life.
Which one should be used in what situation and why?
I am sure that cancel() on PendingIntent has use cases. I cannot name any concrete ones, as I have never seen it used. Typically when you are using a PendingIntent, any "cancel" semantics are on the use of the PendingIntent (e.g., you cancel() the alarm via AlarmManager, you cancel() the notification via NotificationManager), not on the PendingIntent itself.
One place for cancel() on PendingIntent, therefore, would be some place where you pass off a PendingIntent and there is no "cancel" to revert that, or you explicitly wish to use cancel() as the revert mechanism. For example, if you are creating some sort of plugin mechanism, and the plugin sends a PendingIntent to the host app, the plugin might use cancel() to say "stop using that PendingIntent", which the host app would find out about the next time it tried to send() the PendingIntent and got the exception. Personally, I'm not a huge fan of this -- much along the AlarmManager lines, you don't know what resources might be used by the host app if it fails to properly handle this scenario. But, used properly, it could certainly work.
How is that different to this below?
The "below" one is what I would recommend that you use.

Categories

Resources