PendingIntent.cancel()和AlarmManager.cancel()的用法

时间:2015-04-30 20:36:05

标签: android

如果有待处理的警报,PendingIntent.cancel()如何影响AlarmManager。

我是否应该在两个对象(意图和警报管理员)上取消取消以取消警报?有人可以解释他们如何一起工作。

提前致谢。

2 个答案:

答案 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()