如何正确取消ClockManager应用程序中AlarmManager设置的AlarmClock警报?

问题描述

此问题已包含答案hereherehere。但是OP并没有确认它们是否正常工作,在我的情况下,由同一PendingIntent设置的警报不会被取消。 是否可以取消AlarmClock警报?

@Override
protected void onHandleIntent(@Nullable Intent i) {
    Intent i = new Intent(AlarmClock.ACTION_SET_ALARM);
    i.putExtra(AlarmClock.EXTRA_SKIP_UI,true);
    i.putExtra(AlarmClock.EXTRA_HOUR,6);
    i.putExtra(AlarmClock.EXTRA_MINUTES,0);
    i.putExtra(AlarmClock.EXTRA_MESSAGE,"Good Morning");
    i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

    AlarmManager alarmMgr = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
    PendingIntent alarmIntent = PendingIntent.getActivity(
                    this,i,PendingIntent.FLAG_UPDATE_CURRENT);
    alarmMgr.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,SystemClock.elapsedRealtime(),alarmIntent);
    Log.d(TAG,"Alarm set");

    try {
        Thread.sleep(15000);
        alarmMgr.cancel(alarmIntent);
        Log.i(TAG,"Alarm canceled");
    } catch (InterruptedException e) {
        e.printstacktrace();
    }
}

代码输出预期:

Alarm set
Alarm canceled

但是它不会取消设置的警报。我在做什么错了?

解决方法

因此,我发现我需要使用ACTION_DISMISS_ALARM而不是ACTION_SET_ALARM 。它可以让您取消闹钟中已设置的闹钟。

答案hereherehere建议取消对我不起作用并且也未确定对问题作者也有效的PendingIntent。

我认为为什么无法从AlarmManager取消PendingIntent的解释可能是因为存在PendingIntent可以让您执行某些操作或稍后发送该意图。一旦完成(已经发送了意图),就无法撤消它。例如,您可以取消通知,但不能取消从通知中打开应用程序(执行的意图或操作),因为它已经完成。而且,就我而言,这是我需要为其解除警报的另一个应用程序,因此也许我不应该希望能够撤消该操作。 因此,为了消除或取消警报,您需要使用操作ACTION_DISMISS_ALARM发送新的意图。

如下所述替换try / catch块可以正确设置并取消警报:

try {
    if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M) {
        return;
    }
    Thread.sleep(15000);
    Intent ci = new Intent(AlarmClock.ACTION_DISMISS_ALARM);
    ci.setData(i.getData());
    alarmIntent = PendingIntent.getActivity(this,ci,0);
    alarmMgr.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,SystemClock.elapsedRealtime(),alarmIntent);
    Log.i(TAG,"Alarm cancelled");
} catch (InterruptedException e) {
    e.printStackTrace();
}

但是,这仅适用于API级别23 + ,并且不会像ACTION_SET_ALARM中那样让您SKIP_UI。

,

我遇到了同样的问题,并且阅读了您在问题中提到的那些主题。是的,它们不起作用。这就是我设法使其工作的方式:

设置闹钟:

 public static void setAlarm(Context context,int requestCode,int hour,int minute){


    AlarmManager alarmManager =( AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    Intent intent = new Intent(context//same context should be used when canceling the alarm,AlarmReceiver.class);
    intent.setAction("android.intent.action.NOTIFY");

    //setting FLAG_CANCEL_CURRENT makes some problems. and doest allow the cancelAlarm to work properly
    PendingIntent pendingIntent = PendingIntent.getBroadcast(context,1001,intent,0);

    Calendar time = getTime(hour,minute);

    //set Alarm for different API levels
    if (Build.VERSION.SDK_INT >= 23){
        alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,time.getTimeInMillis(),pendingIntent);
    }
    else{
        alarmManager.set(AlarmManager.RTC_WAKEUP,pendingIntent);
    }

取消警报:

 public static void cancelAlarm(Context context,int requestCode){


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

    //define the same intent and pending intent
    Intent intent = new Intent(context//same activity should be used when canceling the alarm,AlarmReceiver.class);
    intent.setAction("android.intent.action.NOTIFY");

    PendingIntent pendingIntent = PendingIntent.getBroadcast(context,0);

    alarmManager.cancel(pendingIntent);
    pendingIntent.cancel();

}

这就像一种魅力。对我而言,要点是,如果我使用 FLAG_CANCEL_CURRENT ,则无法取消警报。当我删除标志并在代码中传递0时,便可以成功删除警报。 我不确定其他标志,因为我没有尝试过。您也可以尝试更改您的标志或将其删除。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...