取消AlarmManager的问题 - PendingIntent

时间:2010-09-09 15:34:42

标签: android android-pendingintent

我有一个应用程序,提醒人们完成他们的任务。所以有一个PendingIntent,现在用户可以在他想要的时候删除警报。在此代码中,只有一个PendingIntent用于多个用户警报,因此我很难在取消意图附加项为"pill"的特定警报。其余警报不应取消。我对这个问题一无所知。希望我很清楚。谢谢

Intent intent = new Intent(this, AlarmNotifyReceiver.class);
intent.putExtra("Name_pill", "pill");
sender = PendingIntent.getBroadcast(this,
DatabaseConstants.NOTIFICATION_ID + 1, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP,cal.getTimeInMillis(), sender);
updateTheFlag(pillName[(pillName.length-1)]);

5 个答案:

答案 0 :(得分:12)

根据Android文档,为了停止闹钟,您应该使用相同的数据创建Intent,但必须使用相同的附加内容:

  

public void cancel(PendingIntent操作)

     

删除具有匹配Intent的所有警报。任何类型的警报,其意图与此匹配>一个(由 filterEquals(Intent)定义)将被取消。

filterEquals(Intent)

  

public boolean filterEquals(Intent other)

     

确定两个意图是否相同以进行意图解析(过滤)。 >也就是说,如果他们的行为,数据,类型,类别和类别是相同的。 这不会比较意图中包含的任何额外数据。

答案 1 :(得分:5)

正如我在评论中所说,您似乎只需要重新创建完全相同的PendingIntent对象,并将相同的Extras放入其中。然后,你打电话

am.cancel(sender);

应取消您的特定警报。我个人无法找到更好的方法。我发现此信息是为了确认我的期望elsewhere

它的内容如下:

  

必须取消重复警报以阻止它们。 AlarmManager提供了一个cancel()方法,该方法需要与创建intent相同的intent类。这是你可以取消闹钟的方法。

     

alarmManager.cancel(的PendingIntent);

     

请注意,pendingIntent对象不需要是同一个对象。创建警报时,操作,类,类别等意图字段应相同。意图用于识别取消它的警报。

在重复警报的情况下,如果我没有弄错的话,应该以相同的方式取消一次性警报。

我无法自己更彻底地测试它,因为我在工作,但这应该有效。

答案 2 :(得分:1)

我认为需要提及getBroadcast()中的 requestCode 参数。我同意所有警报将被取消,与给定的意图相匹配。但是,在定义用于取消的 PendingIntent 时,可以通过使用唯一 requestCode 使警报唯一。因此,只有那些具有相同意图 requestCode 的警报才会被取消:

int TIMER_1 = 1;
int TIMER_2 = 2;
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
Intent i = new Intent(this, AppReciever.class);
i.putExtra("timer", "one");
PendingIntent pending = PendingIntent.getBroadcast(this, TIMER_1, i,
            PendingIntent.FLAG_CANCEL_CURRENT);
Calendar cal = Calendar.getInstance();
am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pending);

然后根据this检查PendingIntent是否存在:

PendingIntent pending1 = PendingIntent.getBroadcast(this, TIMER_2, i, 
                PendingIntent.FLAG_NO_CREATE);
boolean alarmUp = (pending1 != null);

alarmUp false (注意FLAG_NO_CREATE用于在不存在的情况下不创建新的)所以尝试使用相同的 requestCode

PendingIntent pending2 = PendingIntent.getBroadcast(this, TIMER_1, i, 
                PendingIntent.FLAG_NO_CREATE);
alarmUp = (pending2 != null);

alarmUp true ,现在尝试使用新意图包含不同的额外内容:

Intent i2 = new Intent(this, AppReciever.class);
i2.putExtra("timer", "two");
pending2 = PendingIntent.getBroadcast(this, TIMER_1, i2, 
                PendingIntent.FLAG_NO_CREATE);
alarmUp = (pending2 != null);

alarmUp也将是 true ,因为ii2是相同的,但额外的不是,所以现在您可以删除此警报:

am.cancel(pending2);

答案 3 :(得分:0)

  

因此有一个待定意图,现在用户可以删除alram   他想要。这个代码只有一个未决意图   多个用户警报因此我对取消该特定而感到困惑   警报哪里有额外的药丸

intent.putExtra("Name_pill", "pill");

额外的工作不会取消您的未决意图。

pendingIntent.cancel()将仅删除使用相同filterEquals(Intent)触发的待处理意图,并且该方法不会比较给予意图的任何额外数据。

这是来自android filterEquals(Intent)

的开发者网站的包含
  

为了意图的目的,确定两个意图是否相同   分辨率(过滤)。也就是说,如果他们的行动,数据,类型,类,   和类别是一样的。这不会比较任何额外的数据   包含在意图中。

如果我们考虑您的方案,那么当您将Extra传递给当时的意图时,您只需要在参数中给出的某些sharedpreference中保存唯一ID,并且您应该记住一件事该ID必须是唯一的。

并且当您想要取消该警报时,只需使用该已保存的ID传递相同的意图并取消pendingintent

  

创建

preference_saved_value =  DatabaseConstants.NOTIFICATION_ID + 1
sender = PendingIntent.getBroadcast(this,
preference_saved_value, intent,
PendingIntent.FLAG_UPDATE_CURRENT)
  

CANCEL

sender = PendingIntent.getBroadcast(this, 
preference_saved_value, intent,PendingIntent.FLAG_UPDATE_CURRENT);  
sender.cancel()

答案 4 :(得分:0)

正如在android文档中所声明的那样,有意图的意图与Intent.filterEquals相同,但具有不同的请求代码被认为是不同的:

  

如果您确实需要多个不同的PendingIntent对象,请执行此操作   同时(例如使用两个显示的通知   在同一时间),那么你需要确保有一些东西   将他们与不同的人联系起来是不同的   PendingIntents。这可以是所考虑的任何Intent属性   Intent.filterEquals,或提供给的不同请求代码整数   getActivity(Context,int,Intent,int),getActivities(Context,int,   Intent [],int),getBroadcast(Context,int,Intent,int)或   getService(Context,int,Intent,int)。

因此,您可以根据它们分配不同的请求代码并取消待处理的意图,并忘记额外的意图。

有一个有趣的场景我发现了这种行为:

我在我的代码中安排了一个警报并在设备上运行但从未取消它。然后我更改了请求代码并再次运行它。因此创建了一个新的警报。我取消了新警报,但警报仍在执行以前的代码。我很困惑为什么没有取消闹钟。在我发现它来自前面的代码与不同的请求代码后,我卸载了应用程序并再次安装它,问题解决了。