问题描述
此问题已包含答案here,here和here。但是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
。它可以让您取消闹钟中已设置的闹钟。
答案here,here和here建议取消对我不起作用并且也未确定对问题作者也有效的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时,便可以成功删除警报。 我不确定其他标志,因为我没有尝试过。您也可以尝试更改您的标志或将其删除。