我正在使用以下代码取消所有闹钟并重置它们:
for (int i = 0; i < mArrayList.size(); i++) {
Intent receiverIntent = new Intent(mContext, AlarmReceiver.class);
int _id = (int) mArrayList.get(i).getDateMillis(); //(int) System.currentTimeMillis();
PendingIntent sender = PendingIntent.getBroadcast(mContext, _id, receiverIntent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarmManager = (AlarmManager) mContext.getSystemService(mContext.ALARM_SERVICE);
alarmManager.cancel(sender);
setAlarm(mContext, receiverIntent, mArrayList.get(i).getType(), _id, sender, alarmManager);
}
public static void setAlarm(Context context, Intent receiverIntent, String typ, long timeMillis, PendingIntent pendingIntent, AlarmManager
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(timeMillis);
long sdl = calendar.getTimeInMillis();
String notificationTitle = "My Title";
String notificationText = "My Text";
receiverIntent.putExtra("notificationTitle", notificationTitle);
receiverIntent.putExtra("notificationText", notificationText);
receiverIntent.putExtra("notificationDateTime", sdl);
alarmManager.set(AlarmManager.RTC_WAKEUP, sdl, pendingIntent);
}
问题是,当我第一次调用CancelAllAlarms()
然后设置我的警报时,新警报会创建得非常好,但旧警报不会被删除。
所以如果我第一次做adb shell dumpsys alarm > D:\test.txt
我有大约200个条目,那么下一个应用程序运行我有大约400,然后600等...
修改
我更改了我的代码,因为我现在将生成的ID存储在DB中,工作正常。所以我的代码已变得安静显着:
Intent receiverIntent = new Intent(mContext,AlarmReceiver.class); AlarmManager alarmManager =(AlarmManager)mContext.getSystemService(mContext.ALARM_SERVICE);
String[] alarms = getAllAlarmsFromDB(databaseHAlarms, databaseHAlarms.tableName_alarms);
for (int i = 0; i < alarms.length; i++) {
//alarms[i] now holds the ID set before (see codee below)
PendingIntent sender = PendingIntent.getBroadcast(mContext, Integer.parseInt(alarms[i]), receiverIntent, PendingIntent.FLAG_CANCEL_CURRENT);
alarmManager.cancel(sender);
}
for (int i = 0; i < mArrayList.size(); i++) {
long timeMillis = mArrayList.get(i).getDateMillis();
int _id = Integer.parseInt(String.valueOf(mArrayList.get(i).getDateMillis()).substring(0, 8));
PendingIntent sender = PendingIntent.getBroadcast(mContext, _id, receiverIntent, PendingIntent.FLAG_CANCEL_CURRENT);
insertAlarmIntoMySQL(databaseHAlarms, getMD5(timeMillis + ""), String.valueOf(mArrayList.get(i).getDateMillis()).substring(0, 8));
alarmManager.set(AlarmManager.RTC_WAKEUP, sdl, sender);
}
答案 0 :(得分:2)
您需要将传递给PendingIntent
的{{1}}传递给alarmManager.cancel()
。
在您的代码中alarmManager.set()
会有所不同,因此_id
将不相等,因此取消将无效。
ID应该是唯一的(除非您总是要取消所有ID),但是当您想要取消特定警报时,您需要知道创建它时PendingIntent
使用的ID,并使用完全相同的ID取消它。
我建议将ID存储在SQLite数据库中。
答案 1 :(得分:2)
除了用户13的回答,您必须在FLAG_UPDATE_CURRENT
上使用PendingIntent
。
总而言之,请务必使用相同的Context
和id
并使用FLAG_UPDATE_CURRENT
:
启动闹钟:
PendingIntent sender = PendingIntent.getBroadcast(mContext, id, receiverIntent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.set(AlarmManager.RTC_WAKEUP, time, sender);
停止闹铃:
PendingIntent sender = PendingIntent.getBroadcast(mContext, id, receiverIntent, PendingIntent.FLAG_CUPDATE_CURRENT);
alarmManager.cancel(sender);
嗯,不完全清楚/记录为什么FLAG_CANCEL_CURRENT
无效,但我在这里经常读到这个。文档告诉我们,这会取消现有的PendingIntent
并创建一个新的,如果您想更改extra data
内的某些intent
,则可以使用此项。
FLAG_UPDATE_CURRENT
描述如下:
如果您要创建只有附加内容更改的意图,并且不关心接收到您之前的PendingIntent的任何实体将能够使用您的新附加功能启动它,即使它们未明确指定,也可以使用给予它。
从这两个描述中,如果您使用alarmManager.cancel()
,我无法理解为什么它不能与FLAG_CANCEL_CURRENT
一起使用。也许是因为PendingIntent
取消并在FLAG
之前通过alarmManager.cancel()
重新创建了alarmManager.set()
。
对于棉花糖,有一些新的情况。取消应该像以前一样工作,没有变化。但是,如果设备处于打盹模式,则使用setAndAllowWhileIdle()
设置闹钟将无效。描述您必须使用setExactAndAllowWhileIdle()
,setAlarmClock()
或if (Build.VERSION.SDK_INT >= 23) {
PendingIntent sender = PendingIntent.getBroadcast(mContext, id, receiverIntent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, time, sender);
} else {
PendingIntent sender = PendingIntent.getBroadcast(mContext, id, receiverIntent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.set(AlarmManager.RTC_WAKEUP, time, sender);
}
的文档。
但是,如果您的应用程序需要在DOZE上发出警告,那么这样做!因此,要为Marshmallow准备应用程序,您应该检查API版本并设置它所依赖的方法。
{{1}}