android - 如何避免重复 PendingIntents

标签 android android-intent android-pendingintent

嗨!

我在复制 PendingIntents 时遇到了麻烦。我的应用程序有从应用程序的 onCreate 开始的服务,执行一些异步任务并自行停止。 问题是在每次应用程序启动时,我在 AlarmManager 中都有一组来自 DB 的新 PendingIntents(完全相同),但它们不会取消以前的,即使使用 FLAG_CANCEL_CURRENT。我通过“adb shell dumpsys alarm”确定这一点,
这是异步任务的 onPostExecute: protected void onPostExecute(游标 c) {

        while (c.moveToNext())
        {
            int _id = c.getInt(c.getColumnIndex(Maindb._ID));
            long remind_timestamp = c.getLong(c
                    .getColumnIndex(Maindb.REMIND_TIMESTAMP));
            String remind_name = c.getString(c.getColumnIndex(Maindb.NAME));
            String remind_description = c.getString(c
                    .getColumnIndex(Maindb.DESCRIPTION));

            Log.i("Service reminders : id = " + _id + "; REMIND_TIMESTAMP="
                    + remind_timestamp + "; NAME = " + remind_name
                    + "; DESCRIPTION=" + remind_description);

            Intent myIntent = new Intent(ReminderService.this,
                    AlarmReceiver.class);

            myIntent.putExtra(RemindDialog.REMIND_DIALOG_ID, _id);
            myIntent.putExtra(RemindDialog.REMIND_DIALOG_NAME, remind_name);
            myIntent.putExtra(RemindDialog.REMIND_DIALOG_DESCRIPTION,
                    remind_description);
            myIntent.putExtra(RemindDialog.REMIND_DIALOG_TIMESTAMP,
                    remind_timestamp);

            pendingIntent = PendingIntent.getService(ReminderService.this,
                    _id, myIntent, PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT);

            AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);

            alarmManager.set(AlarmManager.RTC_WAKEUP, remind_timestamp,
                    pendingIntent);
            Log.i("Successfully setted alarm for ID:TIMESTAMP = " + _id
                    + ":" + remind_timestamp);


        }

        Log.d("Closing cursor");
        c.close();

        Log.d("Nothing else to do, Stoping the services by himself");
        stopSelf();

    }

第二次应用程序启动后“adb shell dumpsys alarm”的输出如下所示:

RTC_WAKEUP #26: Alarm{42096e70 type 0 com.} type=0 when=+93d9h0m54s107ms repeatInterval=0 count=0 operation=PendingIntent{4283e8b8: PendingIntentRecord{426ab530 com.startService}}

RTC_WAKEUP #25: Alarm{41dff7f8 type 0 com.} type=0 when=+93d9h0m54s107ms repeatInterval=0 count=0 operation=PendingIntent{41f1e730: PendingIntentRecord{41e7e1b0 com.startService}}

RTC_WAKEUP #24: Alarm{42161b60 type 0 com.} type=0 when=+76d19h50m54s107ms repeatInterval=0 count=0 operation=PendingIntent{428494d8: PendingIntentRecord{42705b90 com.startService}}

RTC_WAKEUP #23: Alarm{41ef50a8 type 0 com.} type=0 when=+76d19h50m54s107ms repeatInterval=0 count=0 operation=PendingIntent{41f1de18: PendingIntentRecord{41efdcd0 com.startService}}

RTC_WAKEUP #22: Alarm{42549b40 type 0 com.} type=0 when=+51d5h30m54s107ms repeatInterval=0 count=0 operation=PendingIntent{428697e8: PendingIntentRecord{427c9890 com.startService}}

RTC_WAKEUP #21: Alarm{41f2fe20 type 0 com.} type=0 when=+51d5h30m54s107ms repeatInterval=0 count=0 operation=PendingIntent{41fb31a0: PendingIntentRecord{41f3d018 com.startService}}

RTC_WAKEUP #20: Alarm{4269f008 type 0 com.} type=0 when=+21d10h30m54s107ms repeatInterval=0 count=0 operation=PendingIntent{428706f0: PendingIntentRecord{427fd1f0 com.startService}}

RTC_WAKEUP #19: Alarm{41fb1428 type 0 com.} type=0 when=+21d10h30m54s107ms repeatInterval=0 count=0 operation=PendingIntent{41f3c958: PendingIntentRecord{4212d098 com.startService}}

RTC_WAKEUP #18: Alarm{426aa948 type 0 com.} type=0 when=+16d14h16m54s107ms repeatInterval=0 count=0 operation=PendingIntent{42875fb8: PendingIntentRecord{4282bf98 com.startService}}

RTC_WAKEUP #17: Alarm{42554a70 type 0 com.} type=0 when=+16d14h16m54s107ms repeatInterval=0 count=0 operation=PendingIntent{41ec39e8: PendingIntentRecord{426a0620 com.startService}}

所以,主要问题是为什么我的 PendingIntents 会重复,因为乍一看,第一次和第二次启动应该完全相同(输入 Cursor 完全相同)。

谢谢!对不起我的英语。

最佳答案

您可能已经替换了 PendingIntent 以便您没有重复项。但是,您还没有取消之前使用 AlarmManager 安排的警报。为此,您需要调用:

alarmManager.cancel(pendingIntent);

做之前:

alarmManager.set(AlarmManager.RTC_WAKEUP, remind_timestamp, pendingIntent);

这将取消与传递的 PendingIntent 相匹配的任何警报。

编辑:以上答案对 OP 没有帮助,可能是错误的(参见 A--C 的评论)

替换 PendingIntent 时,您需要使用 PendingIntent.FLAG_UPDATE_CURRENT 而不是 PendingIntent.FLAG_CANCEL_CURRENT。这应该只会产生 1 个预定的警报。

问题是,通过在创建新的 PendingIntent 时取消现有的 PendingIntentAlarmManager 无法确定您正在安排的警报正在被替换另一个(因为它无法比较 PendingIntent 因为旧的不再存在)。

关于android - 如何避免重复 PendingIntents,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14549360/

相关文章:

java - AlarmManager 第二次过早触发 PendingIntent

php - 如何在不编码的情况下使用 Volley 进行多部分?

java - 如何在android中的整个应用程序上检测飞行模式

android - 如何解决 android api 30+ 中的 "Missing PendingIntent mutability flag"lint 警告?

Android:打开短信 Intent

java - Intent 后抽屉导航检查错误

android - 警报没有唤醒我的服务

java - 将 HashMap 数据保存到 SQLite

android - 如何在 ListView 中选择另一个项目之前保持 ListView 内容的更改颜色不变?

android - ContentValues 放置方法