Android: 使用 AlarmManager 设置所有 PendingInents

我把闹钟设成这样:

alarmManager.set(AlarmManager.RTC_WAKEUP, alarmTime, pendingEvent);

我想把之前设置的所有警报都移除,清除它们。

有没有什么方法可以让我做到这一点,或者获取所有当前设置的警报,以便我可以手动删除它们?

74103 次浏览

您需要创建挂起的意图,然后取消它

 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());
}

你不必一直提到它。只要像创建它时定义的那样定义一个新的 PendingInent 即可。

例如:

如果我创建了一个像下面这样由 AlarmManager 发出的 PendingInant:

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);

然后,在你的其他代码(甚至是其他活动)的某个地方,你可以这样取消:

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);

这里重要的是使用完全相同的数据和操作以及其他标准来设置 PendingInent,就像这里所说的 http://developer.android.com/reference/android/app/AlarmManager.html#cancel%28android.app.PendingIntent%29一样

要取消警报,您需要重新创建相同的 PendingInent 并传递相同的请求代码。

因此,我已经创建了一个 AlarmUtils,以帮助我保存所有的请求代码在首选项中取消它在未来,如果它是需要的。您只需使用以下类并调用以下方法:

  • addAlarm添加新的警报并传递请求代码。
  • 要移除 cancelAlarm报警器,需要重新创建相同的
    意图和传递相同的请求代码。
  • hasAlarm来验证是否添加了该警报,您需要重新创建 传递相同的请求代码。
  • cancelAllAlarms删除设置的所有警报。

我的报警器

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();
}
}

如果将 PendingInentid 保存在 SharedPreferences 或 db 中,则在 安卓系统重启你的包裹强制停止时将得到错误的值

您可以将以前的所有 PendingInent 保存到另一个新的 PendingInent 中,然后在以后取消所有

比如说

    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);
}

取消所有以前的挂起意图

    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();
}
}
}

如果重新创建 PendingInant:

PendingIntent pendingIntent = PendingIntent.getBroadcast(
context, 0, newIntent, PendingIntent.FLAG_CANCEL_CURRENT);