如果有待处理的警报,PendingIntent.cancel()如何影响AlarmManager。
我是否应该在两个对象(意图和警报管理员)上取消取消以取消警报?有人可以解释他们如何一起工作。
提前致谢。
答案 0 :(得分:2)
注册PendingIntents
PendingIntent实例可以通过工厂方法PendingIntent.getActivity(),PendingIntent.getService(),PendingIntent.getBroadcast()获得。
然而,除了获取PendingIntent实例之外,ActivityManager在内部缓存/元数据文件中注册PendingIntent(如果它不存在)。相反,如果确实存在,则返回先前注册的实例。
例如,
public static PendingIntent getActivity(Context context, int requestCode,
Intent intent, int flags) {
String packageName = context.getPackageName();
String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
context.getContentResolver()) : null;
try {
intent.setAllowFds(false);
IIntentSender target =
ActivityManagerNative.getDefault().getIntentSender(
IActivityManager.INTENT_SENDER_ACTIVITY, packageName,
null, null, requestCode, new Intent[] { intent },
resolvedType != null ? new String[] { resolvedType } : null, flags);
return target != null ? new PendingIntent(target) : null;
} catch (RemoteException e) {
}
return null;
}
正如文件所述:
/**
* Retrieve a PendingIntent that will start a new activity, like calling
* {@link Context#startActivity(Intent) Context.startActivity(Intent)}.
* Note that the activity will be started outside of the context of an
* existing activity, so you must use the {@link Intent#FLAG_ACTIVITY_NEW_TASK
* Intent.FLAG_ACTIVITY_NEW_TASK} launch flag in the Intent.
...
* @return Returns an existing or new PendingIntent matching the given
* parameters. May return null only if {@link #FLAG_NO_CREATE} has been
* supplied.
仅取消PendingIntent
以下是取消的方式:
/**
* Cancel a currently active PendingIntent. Only the original application
* owning an PendingIntent can cancel it.
*/
public void cancel() {
try {
ActivityManagerNative.getDefault().cancelIntentSender(mTarget);
} catch (RemoteException e) {
}
}
文档说明应用程序可以为您取消PendingIntent。实质上,这意味着ActivityManager尝试匹配PendingIntent并在匹配的PendingIntent存在的情况下删除元数据/缓存条目。
如果您尝试使用标志FLAG_NO_CREATE应用先前取消或未注册的PendingIntent,则返回null。
通过AlarmManager取消PendingIntent
通过AlarmManager取消显然有所不同,因为它删除了IAlarmManager的缓存/元数据文件中已注册的PendingIntent,并且从我注意到深入到Android源代码中,当警报被删除时,没有通过ActivityManager取消。 / p>
public void cancel(PendingIntent operation) {
try {
mService.remove(operation); IAlarmManager instance
} catch (RemoteException ex) {
}
}
<强>结论强>
注册后,您必须通过AlarmManager取消闹钟,取消PendingIntent本身,并且AlarmManager的闹钟取消过程没有任何共同之处。
希望,我澄清了你的疑虑。
答案 1 :(得分:0)
将我的2美分加到dawid gdanski的优秀答案中。
在警报管理器上调用取消足以阻止警报触发。但是,您需要传递设置闹钟时使用的相同Pending Intent。
所以
PendingIntent pc = PendingIntent.getBroadcast(getApplicationContext(),
someid,
someintent,
PendingIntent.FLAG_UPDATE_CURRENT);
//to set
alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime(),
60000, //1 min
pc);
//to cancel, use the same Pending Intent
if(pc != null) {
alarmManager.cancel(pc);
}
您可以通过将闹钟的周期间隔缩短到30秒来自行测试。请注意,仅取消警报就足以阻止警报发射。
但请记住,Pending Intent仍然没有被取消,如果你想这样做,那么你需要明确取消它。
pc.cancel()