PendingIntent
admin
2024-01-21 04:50:16
0

PendingIntent 可以看作是对 Intent 的一个封装,但它不是立即执行某个行为,而是满足某些条件或者触发某些事件后才执行指定的行为。

获取 PendingIntent 的方法有以下三种,分别是通过 Activity、Service、BroadcastReceiver 获取:

  • 通过 getActivity 系列方法从系统中获取一个用于启动 Activity 的 PendingIntent 对象;
  • 通过 getService 系列方法从系统中获取一个用于启动 Service 的 PendingIntent 对象;
  • 通过 getBroadcast 系列方法从系统中获取一个用于启动 BroadcastReceiver 的 PendingIntent 对象;

以下是相关源码:

public final class PendingIntent implements Parcelable {public static PendingIntent getActivity(Context context, int requestCode,Intent intent, @Flags int flags) {return getActivity(context, requestCode, intent, flags, null);}public static PendingIntent getActivity(Context context, int requestCode,@NonNull Intent intent, @Flags int flags, @Nullable Bundle options) {String packageName = context.getPackageName();String resolvedType = intent != null ? intent.resolveTypeIfNeeded(context.getContentResolver()) : null;try {intent.migrateExtraStreamToClipData(context);intent.prepareToLeaveProcess(context);IIntentSender target =ActivityManager.getService().getIntentSenderWithFeature(ActivityManager.INTENT_SENDER_ACTIVITY, packageName,context.getAttributionTag(), null, null, requestCode, new Intent[] { intent },resolvedType != null ? new String[] { resolvedType } : null,flags, options, context.getUserId());return target != null ? new PendingIntent(target) : null;} catch (RemoteException e) {throw e.rethrowFromSystemServer();}}public static PendingIntent getActivities(Context context, int requestCode,@NonNull Intent[] intents, @Flags int flags) {return getActivities(context, requestCode, intents, flags, null);}public static PendingIntent getActivities(Context context, int requestCode,@NonNull Intent[] intents, @Flags int flags, @Nullable Bundle options) {String packageName = context.getPackageName();String[] resolvedTypes = new String[intents.length];for (int i=0; iintents[i].migrateExtraStreamToClipData(context);intents[i].prepareToLeaveProcess(context);resolvedTypes[i] = intents[i].resolveTypeIfNeeded(context.getContentResolver());}try {IIntentSender target =ActivityManager.getService().getIntentSenderWithFeature(ActivityManager.INTENT_SENDER_ACTIVITY, packageName,context.getAttributionTag(), null, null, requestCode, intents, resolvedTypes,flags, options, context.getUserId());return target != null ? new PendingIntent(target) : null;} catch (RemoteException e) {throw e.rethrowFromSystemServer();}}public static PendingIntent getService(Context context, int requestCode,@NonNull Intent intent, @Flags int flags) {return buildServicePendingIntent(context, requestCode, intent, flags,ActivityManager.INTENT_SENDER_SERVICE);}public static PendingIntent getBroadcast(Context context, int requestCode,Intent intent, @Flags int flags) {return getBroadcastAsUser(context, requestCode, intent, flags, context.getUser());}
}

对于参数 flag 可以有以下状态:

  • FLAG_NO_CREATE:如果当前系统中已经存在一个相匹配的 PendingIntent 对象,将不进行创建,如果不存在,也不会创建该 PendingIntent 对象,而是直接返回 NULL;
  • FLAG_ONE_SHOT:该 PendingIntent 只作用一次,在该 PendingIntent 对象通过 send 方法触发过后,PendingIntent 将自动调用 cancel 进行销毁。如果再次调用 send 方法的话,系统将会返回一个 SendIntentException
  • FLAG_CANCEL_CURRENT:如果当前系统中已经存在一个相匹配的 PendingIntent,那么,将已有的 PendingIntent 取消,再重新生成一个 PendingIntent 对象;
  • FLAG_UPDATE_CURRENT:如果系统中有一个相匹配的 PendingIntent,系统将使用该 PendingIntent 对象,但是,会使用新的 Intent.Extra 来更新之前的 PendingIntent 中的 Intent 数据;

备注:两个 PendingIntent 对等指它们的 operation 一样,且它们的 Intent 的 action、data、categories、components 和 flags 都一样,但它们的 Intent 的 Extra 可以不一样。

PendingIntent 的匹配规则:如果两个 PendingIntent 的 Intent 相同并且 requestCode 也相同,那么这两个 PendingIntent 是相匹配的。

Intent 的匹配规则:如果两个 Intent 的 ComponentName 和 intent-filter 都相同,那么这两个 Intent 是相同的,Extras 不参加 Intent 的匹配过程。以下是 Intent.filterEquals 方法:

public class Intent implements Parcelable, Cloneable {/* * Determine if two intents are the same for the purposes of intent resolution (filtering). Thatis,  * if their action, data, type, identity, class, and categories are the same. This does not compare * any extra data included in the intents. Note that technically when actually matching against an * IntentFilter the identifier is ignored, while here it is directly compared for equality like the * other fields.* Params:* other – The other Intent to compare against.* Returns:* Returns true if action, data, type, class, and categories are the same.*/public boolean filterEquals(Intent other) {if (other == null) {return false;}if (!Objects.equals(this.mAction, other.mAction)) return false;if (!Objects.equals(this.mData, other.mData)) return false;if (!Objects.equals(this.mType, other.mType)) return false;if (!Objects.equals(this.mIdentifier, other.mIdentifier)) return false;if (!(this.hasPackageEquivalentComponent() && other.hasPackageEquivalentComponent())&& !Objects.equals(this.mPackage, other.mPackage)) {return false;}if (!Objects.equals(this.mComponent, other.mComponent)) return false;if (!Objects.equals(this.mCategories, other.mCategories)) return false;return true;}
}

如果是 Android 12 及以上的系统,要求为每个创建的 PendingIntent 对象指定可变性,这样做可以提高应用的安全性。如需声明 PendingIntent 对象是否可变,分别使用 PendingIntent.FLAG_MUTABLE 或 PendingIntent.FLAG_IMMUTABLE 标志。如果在不设置任何可变标志的情况下创建 PendingIntent 对象,系统会抛出 IllegalArgumentException。

在 Android 12 之前的版本中,不带有 FLAG_IMMUTABLE 标记创建的 PendingIntent 默认是可变类型的。

PendingIntent 的使用场景:

  • 通知,在点击通知时执行调起本应用的操作或者其他操作;
  • 闹钟,定时执行某个操作;
  • 桌面小部件,点击小部件时执行某个操作;

参考

Android基础——PendingIntent理解
PendingIntent详解
PendingIntent
PendingIntent的解惑
关于 PendingIntent 您需要知道的那些事

相关内容

热门资讯

华为安卓系统换头,换头技术引领... 你知道吗?最近科技圈可是炸开了锅,华为安卓系统换头的大动作引起了广泛关注。这可不是什么小打小闹,而是...
安卓系统支持国语吗,畅享本地化... 你有没有想过,当你拿起手机,打开那个熟悉的安卓系统时,它是不是真的支持我们的大国语言——国语呢?这个...
电脑安装安卓完美系统,电脑安装... 你有没有想过,把安卓系统装在你的电脑上,是不是就像给电脑穿上了时尚的新衣?想象那些你手机上爱不释手的...
安卓oppo系统更新包,体验流... 你有没有发现,你的OPPO手机最近是不是变得有点儿不一样了?没错,这就是安卓系统更新包的魔力!今天,...
安卓系统车载导航更新了,安卓系... 你知道吗?最近安卓系统车载导航可是来了一次大变身呢!是不是觉得开车的时候导航系统有点儿慢吞吞的,信息...
安卓移动点餐系统报告,助力餐饮... 你有没有发现,现在点外卖已经成了生活中不可或缺的一部分?手机轻轻一点,美食就能送到家门口,是不是超级...
国产系统为什么都是安卓,兼容性... 你有没有发现,现在市面上很多国产手机和电脑,虽然品牌各异,但操作系统大多都是安卓呢?这究竟是为什么呢...
台电如何删除安卓系统,轻松删除... 你有没有遇到过这种情况:手机里装了安卓系统,但是台电的某些功能让你觉得不爽,想要彻底删除它?别急,今...
安卓系统的id在哪找,揭秘设备... 你有没有遇到过这种情况:手机里装了各种各样的应用,有时候想找某个应用,却怎么也找不到它的ID。别急,...
华为怎么退出安卓系统,探索退出... 你知道吗?最近华为可是闹得沸沸扬扬的,他们竟然要退出安卓系统了!这可不是一个简单的决定,背后可是有着...
windows系统上安装安卓,... 你有没有想过在Windows系统上也能用上安卓系统呢?没错,这可不是天方夜谭,而是完全可行的。今天,...
安卓手机系统设置apk,轻松生... 你有没有发现,你的安卓手机最近有点儿“懒”了呢?运行速度慢了下来,应用层出不穷,你有没有想过,是不是...
土鸡视频安卓系统下载,轻松享受... 你有没有想过,一只土鸡在高清视频里跳起舞来会是怎样的场景?想象那毛茸茸的小家伙,欢快地摇着尾巴,在绿...
电脑下载安卓系统软件,探索安卓... 你有没有想过,你的电脑也能装上安卓系统呢?没错,就是那个我们手机上常用的安卓系统!今天,就让我带你一...
欧版安卓系统怎么样,探索欧版安... 你有没有想过,为什么安卓系统在全球范围内这么受欢迎呢?尤其是那个传说中的欧版安卓系统,它到底有什么特...
dx220纯音系统和安卓系统,... 你有没有想过,为什么有时候听音乐的感觉就是那么不一样呢?是不是因为你的音响系统不够强大,或者是你的操...
安卓系统版本名字,版本变迁之旅 你有没有发现,每次打开手机,系统都会提醒你更新安卓系统版本?那些听起来像是外星语言的名字,是不是让你...
安卓以外的系统有什么,多系统平... 你有没有想过,除了安卓这个大家伙,还有其他操作系统在默默耕耘呢?是的,你没听错,这个世界不仅仅只有安...
怎么看安卓几系统,如何识别与选... 亲爱的读者们,你是否也像我一样,对安卓系统的更新换代充满了好奇?安卓系统,这个陪伴我们手机生活的“老...
安卓版系统怎么删除,副标题被成... 手机里的安卓版系统里是不是也堆满了你不想再看到的文件和应用程序?别急,今天就来手把手教你如何轻松删除...