【问题标题】:Delete alarm from AlarmManager using cancel() - Android使用 cancel() 从 AlarmManager 删除警报 - Android
【发布时间】:2013-01-07 06:23:05
【问题描述】:

我正在尝试用两种不同的方法创建和删除警报,这两种方法都在应用程序逻辑的不同时刻调用。

但是,当我调用 AlarmManager 的 cancel() 方法时,警报并没有被删除。

这是我的addAlarm() 方法:

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

Intent intent = new Intent(PROX_ALERT_INTENT);
intent.putExtra("ALERT_TIME", alert.date);
intent.putExtra("ID_ALERT", alert.idAlert);
intent.putExtra("TITLE", alert.title);
intent.putExtra("GEO_LOC", alert.isGeoLoc);
PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext,
        alert.idAlert, intent, PendingIntent.FLAG_CANCEL_CURRENT);

Calendar calendar = Calendar.getInstance();
calendar.setTime(alert.date);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
Log.e("ADD ALERT - WithoutGeoLoc - ",alert.toString());

这是我的 deleteAlarm() 方法:

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

Intent intent = new Intent(PROX_ALERT_INTENT);
intent.putExtra("ALERT_TIME", alert.date);
intent.putExtra("ID_ALERT", alert.idAlert);
intent.putExtra("TITLE", alert.title);
intent.putExtra("GEO_LOC", alert.isGeoLoc);
PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext,
        alert.idAlert, intent, PendingIntent.FLAG_CANCEL_CURRENT);

alarmManager.cancel(pendingIntent);
Log.e(TAG,"REMOVE ALERT - without GeoLoc"+alert.toString());

这是我的 Logcat:

01-23 17:44:07.411: E/ADD ALERT - WithoutGeoLoc -(18789): Alert [latitude=0.0, longitude=0.0, title=bfwu, comments=null, address=null, currency=hrk, idAlert=1, date=Sat Feb 23 17:44:04 CET 2013, isGeoLoc=null]
01-23 17:44:13.032: E/REMOVE ALERT without GeoLoc - (18789): Alert [latitude=0.0, longitude=0.0, title=bfwu, comments=null, address=null, currency=hrk, idAlert=1, date=Sat Feb 23 17:44:04 CET 2013, isGeoLoc=null]

这是 AlarmManager 中的 pendingIntent 列表

Current Alarm Manager state:
Realtime wakeup (now=2013-01-23 17:44:37):
RTC_WAKEUP #48: Alarm{2c1d0588 type 0 com.my.app}
type=0 when=+364d23h59m33s288ms repeatInterval=0 count=0
operation=PendingIntent{2c0a6cb0: PendingIntentRecord{2c1d04e8 com.my.app  broadcastIntent}}
RTC_WAKEUP #47: Alarm{2c2298a0 type 0 com.my.app}
type=0 when=+30d23h59m27s360ms repeatInterval=0 count=0
operation=PendingIntent{2c292af8: PendingIntentRecord{2c22a628 com.my.app broadcastIntent}}

几个注意事项:

  • RTC_WAKEUP #47 是我原来的闹钟
  • RTC_WAKEUP #48 是一个新警报,应该覆盖 #47 而不是创建一个新警报。

我使用 Intent 的 filterEquals() 方法比较了我的 add 和 delete 方法中的两个意图(不是 pendingIntents),该方法返回true ...但是警报没有被删除。我做错了什么?


更新

这是我的 saveAlert() 方法,它调用 addAlarm() 和 deleteAlarm()

private void saveAlert() {
    // *** If Modifying Alert => REMOVE OLD ALERT (then add new one)
    Intent intent1 = null, intent2 = null;

    if (alert.idAlert != null) {
        if (alert.isGeoLoc == null || alert.isGeoLoc == false) {
            intent2 = ProximityService.removeProximityAlertWithoutGeoLoc(getApplicationContext(), devisesApp.alertsGlobal.getAlertById(alert));
        } else {
            ProximityService.removeProximityAlert(getApplicationContext(), alert);
        }
    }
    // *** Add Alert
    if (alert.isGeoLoc == null || alert.isGeoLoc == false) {
        intent1 = ProximityService.addProximityAlertWithoutGeoLoc(getApplicationContext(), alert, devisesApp.alertsGlobal);
    } else {
        ProximityService.addProximityAlert(getApplicationContext(), alert, devisesApp.alertsGlobal);
    }

    Log.i(TAG, "[saveAlert] Alert ID : " + alert.idAlert);
    devisesApp.alertsGlobal.addById(alert);
    Log.i("INTENT EQUALS", intent1.filterEquals(intent2) + ""); // This returns true
}

【问题讨论】:

  • 只是出于好奇,您是如何获得设备的 AlarmManager PendingIntents 列表的?
  • adb shell dumpsys 警报 > dump.txt
  • 此代码注释有效,因为意图获取新值并且在取消中再次用于设置方法警报管理器中的参数挂起意图时必须使用意图

标签: android alarm android-pendingintent


【解决方案1】:

试试这个标志:

PendingIntent.FLAG_UPDATE_CURRENT

代替:

PendingIntent.FLAG_CANCEL_CURRENT 

所以 PendingIntent 将如下所示:

PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 
        alert.idAlert, intent, PendingIntent.FLAG_UPDATE_CURRENT)  

(确保您使用相同的alert 对象和mContext!)

附注:如果您想要一个全局 AlarmManager,请将 AlarmManager 放在一个静态变量中(并且仅当它是 null 时才对其进行初始化)。

【讨论】:

  • 非常感谢,我已经坚持了好几个小时我把我的标志改为 PendingIntent.FLAG_UPDATE_CURRENT) 现在它就像一个魅力
  • 我也有类似的情况。对于将来偶然发现这篇文章的人来说,也许可以尝试在未决意图上调用 Cancel()。否则,getBroadcast 将始终返回该意图。 (虽然它的警报不会触发事件)
  • +1。还应该使用 '0' 作为标志 - 只要您不取消现有的意图,就无需更新现有的待处理意图。
  • 你能解释一下为什么使用FLAG_CANCEL_CURRENT不能取消吗?在我的理解中,如果 context、pendingIntent 和 requestCode 相同,则可以取消警报。
  • 获得AlarmManager 需要Context 所以我想知道将它存储在静态变量中是否绝对安全——即不会有任何内存泄漏?
【解决方案2】:

取消警报有点令人困惑。您必须传递相同的 ID 和 IntentPending。这是一个例子:

private void resetIntentWithAlarm(int time){


        Intent intentAlarm = new Intent(getApplicationContext(), DownloadService.class);
        intentAlarm.putExtra(Your Key, Your stuff to pass here);

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

        PendingIntent pendingIntent = PendingIntent.getService(
                getApplicationContext(),
                YOUR_ID,
                intentAlarm,
                PendingIntent.FLAG_UPDATE_CURRENT
        );

    if (time != 0) {

        alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (60L * 1000L * time), (60L * 1000L * time), pendingIntent);
        Log.i(TAG, "Alarm setted on for " + time + " mins.");
    }
    // if TIME == Zero, cancel alaram
    else {

        alarmManager.cancel(pendingIntent);
        Log.i(TAG, "Alarm CANCELED. Time = " + time);
    }

【讨论】:

    【解决方案3】:

    在您设置的任何特定时间从警报管理器取消警报:

    Intent intent = new Intent(context, AlarmReceiver.class);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
    AlarmManager am = (AlarmManager) context.getSystemService(ALARM_SERVICE);
    am.cancel(pendingIntent);
    

    【讨论】:

      【解决方案4】:

      如果您想取消警报管理器,只需将 wright id 放入待处理的意图中,然后在警报管理器中为该待处理的意图调用 cancel()。

      【讨论】:

      • cancel() javadoc 说Remove any alarms with a matching Intent. Any alarm, of any type, whose Intent matches this one (as defined by filterEquals(Intent)), will be canceled. requestCode 没有任何影响。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-05-09
      • 2023-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多