Android: Get all PendingIntents set with AlarmManager
I'm setting an alarm like this:
alarmManager.set(AlarmManager.RTC_WAKEUP, alarmTime, pendingEvent);
I'm interested in removing all the alarms that where previously set, clearing them.
Is there a way for me to do that or to get all the a开发者_运维知识库larms that are currently set so that I can delete them manually ?
You don't have to keep reference to it. Just define a new PendingIntent like exactly the one that you defined in creating it.
For example:
if I created a PendingIntent to be fired off by the AlarmManager like this:
Intent alarmIntent = new Intent(getApplicationContext(), AlarmBroadcastReceiver.class);
alarmIntent.setData(Uri.parse("custom://" + alarm.ID));
alarmIntent.setAction(String.valueOf(alarm.ID));
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
PendingIntent displayIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, alarmIntent, 0);
alarmManager.set(AlarmManager.RTC_WAKEUP, alarmDateTime, displayIntent);
Then somewhere in your other code (even another activity) you can do this to cancel:
Intent alarmIntent = new Intent(getApplicationContext(), AlarmBroadcastReceiver.class);
alarmIntent.setData(Uri.parse("custom://" + alarm.ID));
alarmIntent.setAction(String.valueOf(alarm.ID));
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
PendingIntent displayIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, alarmIntent, 0);
alarmManager.cancel(displayIntent);
The important thing here is to set the PendingIntent with exactly the same data and action, and other criteria as well as stated here http://developer.android.com/reference/android/app/AlarmManager.html#cancel%28android.app.PendingIntent%29
You need to create your pending intent and then cancel it
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent updateServiceIntent = new Intent(context, MyPendingIntentService.class);
PendingIntent pendingUpdateIntent = PendingIntent.getService(context, 0, updateServiceIntent, 0);
// Cancel alarms
try {
alarmManager.cancel(pendingUpdateIntent);
} catch (Exception e) {
Log.e(TAG, "AlarmManager update was not canceled. " + e.toString());
}
To cancel an alarm you need to re-create the same PendingIntent and pass the same request code.
So, I have created an AlarmUtils to help me saving all the request codes in the preferences to cancel it in the future if it is needing. All you need is to use the following class and call the following methods:
addAlarm
to add a new alarm and pass a request code.cancelAlarm
to remove an alarm, you need to re-create the same
Intent and pass the same request code.hasAlarm
to verify if that alarm as added, you need to re-create the same Intent and pass the same request code.cancelAllAlarms
to remove ALL alarms setted.
My AlarmUtils
public class AlarmUtils {
private static final String sTagAlarms = ":alarms";
public static void addAlarm(Context context, Intent intent, int notificationId, Calendar calendar) {
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, notificationId, intent, PendingIntent.FLAG_CANCEL_CURRENT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
} else {
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
}
saveAlarmId(context, notificationId);
}
public static void cancelAlarm(Context context, Intent intent, int notificationId) {
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, notificationId, intent, PendingIntent.FLAG_CANCEL_CURRENT);
alarmManager.cancel(pendingIntent);
pendingIntent.cancel();
removeAlarmId(context, notificationId);
}
public static void cancelAllAlarms(Context context, Intent intent) {
for (int idAlarm : getAlarmIds(context)) {
cancelAlarm(context, intent, idAlarm);
}
}
public static boolean hasAlarm(Context context, Intent intent, int notificationId) {
return PendingIntent.getBroadcast(context, notificationId, intent, PendingIntent.FLAG_NO_CREATE) != null;
}
private static void saveAlarmId(Context context, int id) {
List<Integer> idsAlarms = getAlarmIds(context);
if (idsAlarms.contains(id)) {
return;
}
idsAlarms.add(id);
saveIdsInPreferences(context, idsAlarms);
}
private static void removeAlarmId(Context context, int id) {
List<Integer> idsAlarms = getAlarmIds(context);
for (int i = 0; i < idsAlarms.size(); i++) {
if (idsAlarms.get(i) == id)
idsAlarms.remove(i);
}
saveIdsInPreferences(context, idsAlarms);
}
private static List<Integer> getAlarmIds(Context context) {
List<Integer> ids = new ArrayList<>();
try {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
JSONArray jsonArray2 = new JSONArray(prefs.getString(context.getPackageName() + sTagAlarms, "[]"));
for (int i = 0; i < jsonArray2.length(); i++) {
ids.add(jsonArray2.getInt(i));
}
} catch (Exception e) {
e.printStackTrace();
}
return ids;
}
private static void saveIdsInPreferences(Context context, List<Integer> lstIds) {
JSONArray jsonArray = new JSONArray();
for (Integer idAlarm : lstIds) {
jsonArray.put(idAlarm);
}
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = prefs.edit();
editor.putString(context.getPackageName() + sTagAlarms, jsonArray.toString());
editor.apply();
}
}
If save the PendingIntent id in SharedPreference or db, you will get wrong value when Android reboot or your package force-stop
You can save all your previous PendingIntent to another new PendingIntent, then cancel all later
for example
void createSomeAlarmAndSave() {
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, new Intent(this, MyReceiver.class).setAction(ACTION_XXX), 0);
getSystemService(AlarmManager.class).setInexactRepeating(AlarmManager.RTC_WAKEUP, 1000 * 60 * 15, 1000 * 60 * 15, pendingIntent);
PendingIntent pendingIntent1 = PendingIntent.getBroadcast(this, 1, new Intent(this, MyReceiver.class).setAction(ACTION_XXX), 0);
getSystemService(AlarmManager.class).setInexactRepeating(AlarmManager.RTC_WAKEUP, 1000 * 60 * 20, 1000 * 60 * 20, pendingIntent1);
PendingIntent pendingIntent2 = PendingIntent.getBroadcast(this, 2, new Intent(this, MyReceiver.class).setAction(ACTION_XXX), 0);
getSystemService(AlarmManager.class).setInexactRepeating(AlarmManager.RTC_WAKEUP, 1000 * 60 * 25, 1000 * 60 * 25, pendingIntent2);
//save all previous PendingIntent to another new PendingIntent
PendingIntent.getBroadcast(this, 0, new Intent(this, MyReceiver.class).putExtra("previous", new PendingIntent[]{pendingIntent, pendingIntent1, pendingIntent2}), PendingIntent.FLAG_UPDATE_CURRENT);
}
cancel all previous PendingIntent
void cancelAllPreviousAlarm() {
//acquire the dedicated PendingIntent
PendingIntent pendingIntentAllPrevious = PendingIntent.getBroadcast(this, 0, new Intent(this, MyReceiver.class), PendingIntent.FLAG_NO_CREATE);
if (pendingIntentAllPrevious != null) {
try {
pendingIntentAllPrevious.send(this, 0, null, new PendingIntent.OnFinished() {
@Override
public void onSendFinished(PendingIntent pendingIntent, Intent intent, int resultCode, String resultData, Bundle resultExtras) {
for (Parcelable parcelable : intent.getParcelableArrayExtra("previous")) {
//alarm will cancel when the corresponding PendingIntent cancel
((PendingIntent) parcelable).cancel();
}
}
}, null);
pendingIntentAllPrevious.cancel();
} catch (PendingIntent.CanceledException e) {
e.printStackTrace();
}
}
}
If you re-creating the PendingIntent:
PendingIntent pendingIntent = PendingIntent.getBroadcast(
context, 0, newIntent, PendingIntent.FLAG_CANCEL_CURRENT);
精彩评论