如何在时钟应用程序中正确取消由 AlarmManager 设置的 AlarmClock 闹钟?
How to correctly cancel an AlarmClock alarm set by AlarmManager in the Clock app?
这个问题已经有了答案here, here and 。但是他们没有被 OP 确认正在工作,在我的例子中,由同一个 PendingIntent 设置的警报不会被取消。 有没有办法取消闹钟闹钟?
@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, 0, 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
但是并没有取消设置的闹钟。我做错了什么?
我遇到了同样的问题,我阅读了你在问题中提到的那些话题。是的,它们不起作用。这就是我设法让它工作的方式:
设置闹钟:
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,time.getTimeInMillis(),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, 1001, intent, 0);
alarmManager.cancel(pendingIntent);
pendingIntent.cancel();
}
这很有魅力。关键是,对我来说,如果我使用 FLAG_CANCEL_CURRENT 我无法取消警报。当我删除标志并在我的代码中传入0时,我可以成功删除警报。
我不确定其他标志,因为我没有尝试过。您也可以尝试更改标志或删除它们。
所以,我发现我需要使用ACTION_DISMISS_ALARM
而不是ACTION_SET_ALARM
。它可以让您取消闹钟中已经设置的闹钟。
答案 here, here, and 建议取消 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, 0, 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。
这个问题已经有了答案here, here and
@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, 0, 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
但是并没有取消设置的闹钟。我做错了什么?
我遇到了同样的问题,我阅读了你在问题中提到的那些话题。是的,它们不起作用。这就是我设法让它工作的方式:
设置闹钟:
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,time.getTimeInMillis(),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, 1001, intent, 0);
alarmManager.cancel(pendingIntent);
pendingIntent.cancel();
}
这很有魅力。关键是,对我来说,如果我使用 FLAG_CANCEL_CURRENT 我无法取消警报。当我删除标志并在我的代码中传入0时,我可以成功删除警报。 我不确定其他标志,因为我没有尝试过。您也可以尝试更改标志或删除它们。
所以,我发现我需要使用ACTION_DISMISS_ALARM
而不是ACTION_SET_ALARM
。它可以让您取消闹钟中已经设置的闹钟。
答案 here, here, and
我认为,为什么从 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, 0, 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。