警报未取消

时间:2016-06-09 12:29:05

标签: android android-pendingintent android-alarms

我正在使用以下代码取消所有闹钟并重置它们:

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

2 个答案:

答案 0 :(得分:2)

您需要将传递给PendingIntent的{​​{1}}传递给alarmManager.cancel()

在您的代码中alarmManager.set()会有所不同,因此_id将不相等,因此取消将无效。

ID应该是唯一的(除非您总是要取消所有ID),但是当您想要取消特定警报时,您需要知道创建它时PendingIntent使用的ID,并使用完全相同的ID取消它。

我建议将ID存储在SQLite数据库中。

答案 1 :(得分:2)

除了用户13的回答,您必须在FLAG_UPDATE_CURRENT上使用PendingIntent

总而言之,请务必使用相同的Contextid并使用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}}