如何从AlarmManager取消闹钟

47

我遇到了和这个类似的问题。 使用cancel()方法从AlarmManager中删除闹钟 - Android

我试图在应用程序的不同时刻调用两个不同的方法来创建和删除闹钟。然而,当我调用AlarmManager的cancel()方法时,闹钟并没有被删除。

为了设置:

            Intent myIntent = new Intent(getApplicationContext(),
                    SessionReceiver.class);
            PendingIntent pendingIntent = PendingIntent.getBroadcast(
                    getApplicationContext(), 1, myIntent, 0);

            AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);

            alarmManager.set(AlarmManager.RTC, now.getTimeInMillis(),
                    pendingIntent);

为了删除:

    AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
    Intent myIntent = new Intent(getApplicationContext(),
            SessionReceiver.class);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(
            getApplicationContext(), 0, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);

    alarmManager.cancel(pendingIntent);

但这并不会删除已注册的警报。

先谢谢您。

2个回答

111

需要创建与启动AlarmManager时完全相同的PendingIntent,主要问题是使用了不同的requestCode(零而不是一)。

对于快速解决,应该可以这样操作:

AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent myIntent = new Intent(getApplicationContext(), SessionReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
                                 getApplicationContext(), 1, myIntent, 0);

alarmManager.cancel(pendingIntent);

若要使用PendingIntent.FLAG_UPDATE_CURRENT标志,请参见以下内容:

设置:

Intent myIntent = new Intent(getApplicationContext(), SessionReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
                                getApplicationContext(), 1, myIntent, 
                                PendingIntent.FLAG_UPDATE_CURRENT);

AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);

alarmManager.set(AlarmManager.RTC, now.getTimeInMillis(), pendingIntent);

取消:

AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent myIntent = new Intent(getApplicationContext(), SessionReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
                                getApplicationContext(), 1, myIntent, 
                                PendingIntent.FLAG_UPDATE_CURRENT);

alarmManager.cancel(pendingIntent);

哦,我明白了问题所在。我应该使用相同的requestCode!非常感谢你的帮助。 - Vladimir Homola
你能帮我解决 https://stackoverflow.com/questions/51542099/cant-stop-the-ringing-alarm-from-another-activity#51542099 吗?@DanielNugent - Zhu
48
为什么谷歌没有将其实现为 AlarmManager.cancel(int requestCode)?操作系统会处理底层细节,如应用程序命名空间等。这肯定会是一个更加用户友好的 API。 - Someone Somewhere
1
所以基本上requestCode是闹钟的标识符? - Mitulát báti
2
不,requestCode不是闹钟的标识符。PendingIntent才是标识符,而requestCode是PendingIntent的关键属性之一(与底层Intent本身一起,后者具有其自己的标识键)。 - Gabriel
设置是否也会更新(例如到新的触发时间)?还是我必须取消并重新设置? - android developer

6

最初对我也没有起作用,看了很多帖子后,我意识到要取消的挂起意图应该与用于计划闹钟的原始挂起意图相同。 要取消的挂起意图应该设置为相同的操作和相同的数据字段(如果有)被用于设置闹钟。设置相同的操作和数据值后,尽管我没有使用它们,只是取消了闹钟。


这对我有用。在设置闹钟时,我使用FLAG_ONE_SHOT作为待处理标志,使用FLAG_UPDATE_CURRENT进行取消。将FLAG_UPDATE_CURRENT替换为FLAG_ONE_SHOT(在设置闹钟时使用)进行取消操作,得到了期望的结果。 - Trupti Nasit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接