PendingIntent和Intent的区别

本文详细解析了PendingIntent的概念及其应用场景,包括如何与Notification、SmsManager等组件结合使用。

intent英文意思是意图,pending表示即将发生或来临的事情。 
PendingIntent这个类用于处理即将发生的事情。比如在通知Notification中用于跳转页面,但不是马上跳转。 

Intent 是及时启动,intent 随所在的activity 消失而消失。 
PendingIntent 可以看作是对intent的包装,通常通过getActivity,getBroadcast ,getService来得到pendingintent的实例,当前activity并不能马上启动它所包含的intent,而是在外部执行 pendingintent时,调用intent的。正由于pendingintent中 保存有当前App的Context,使它赋予外部App一种能力,使得外部App可以如同当前App一样的执行pendingintent里的 Intent, 就算在执行时当前App已经不存在了,也能通过存在pendingintent里的Context照样执行Intent。另外还可以处理intent执行后的操作。常和alermanger 和notificationmanager一起使用。 
Intent一般是用作Activity、Sercvice、BroadcastReceiver之间传递数据,而Pendingintent,一般用在 Notification上,可以理解为延迟执行的intent,PendingIntent是对Intent一个包装。

PendingIntent这个类封装了一个Intent(意图),它表示即将发送的动作的类型。 这个类的方法主要有两类,一类是getXXX,表示要激活的意图的类型,如activity,service或者是BroadcastReceiver等。另一类是send,表示立即发送这个意图。 

下面是常用的API:  
1. public static PendingIntent getActivity (Context context, int requestCode, Intent intent, int flags, Bundle options)
2. public static PendingIntent getBroadcast (Context context, int requestCode, Intent intent, int flags)
3. public static PendingIntent getService (Context context, int requestCode, Intent intent, int flags)
4. public void send ()

示例:  activity不贴了。  1.PendingIntent单独使用.   下面是activity中的一个button的点击事件所调用的方法.这个方法用于发送一个广播
01. /**
02. * 单独使用pendingIntent
03. *     通过send方法发送intent
04. */
05. public void pendingIntentFunc()
06. {
07. Intent intent = new Intent("com.xxx");
08. intent.putExtra("info","我是info");
09. //其实就跟调用sendBroadcast方法一样
10. PendingIntent pi = PendingIntent.getBroadcast(this0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
11. try
12. {
13. pi.send();//执行PendingIntent中的意图
14. catch (CanceledException e)
15. {
16. e.printStackTrace();
17. }
18. }
定义一个BroadcastReceiver用于接收广播:
01. package com.example.receiver;
02. import android.content.BroadcastReceiver;
03. import android.content.Context;
04. import android.content.Intent;
05. import android.util.Log;
06. import android.widget.Toast;
07. public class MyReceiver extends BroadcastReceiver
08. {
09. private static final String TAG = "MyReceiver";
10. @Override
11. public void onReceive(Context context, Intent intent)
12. {
13. Log.i(TAG,"成功收到广播...");
14. Toast.makeText(context,"info:"+intent.getStringExtra("info"),0).show();
15. }
16. }

清单文件中配置receiver:

1. <receiver android:name="com.example.receiver.MyReceiver">
2. <intent-filter >
3. <action android:name="com.xxx"/>
4. </intent-filter>
5. </receiver>

当点击按钮时,将会发出广播,而且还能接收到intent传来的信息。 logcat打印如下日志:  \

2.PendingIntent配合Notification使用   下面也是activity中的一个按钮的点击事件触发所执行的函数
01. /**
02. * 显示一个通知,点击通知将会激活一个服务
03. */
04. public void sendNotification2()
05. {
06. NotificationManager manager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
07. //        notification的初始化
08. Notification notification = new Notification();
09. notification.icon = R.drawable.ic_launcher;
10. notification.when = System.currentTimeMillis();
11. notification.tickerText = "又来一条新通知";
12. notification.flags = notification.FLAG_AUTO_CANCEL;
13. //        包装一个PendingIntent,当用户点击通知触发一个意图
14. Intent intent = new Intent(this,MyService.class);
15. //        点击通知将启动服务,相当于调用了startService方法
16. PendingIntent contentIntent = PendingIntent.getService(this0,intent, PendingIntent.FLAG_UPDATE_CURRENT);
17. notification.setLatestEventInfo(this,"标题","点我激活一个服务", contentIntent);
18. //        激活通知
19. manager.notify(2,notification);//第一个参数代表的是通知的id
20. }

定义一个服务:

01. package com.example.service;
02.  
03. import android.app.Service;
04. import android.content.Intent;
05. import android.os.IBinder;
06. import android.util.Log;
07.  
08. public class MyService extends Service
09. {
10. private static final String TAG = "MyService";
11.  
12. @Override
13. public IBinder onBind(Intent intent)
14. {
15. return null;
16. }
17.  
18. @Override
19. public void onCreate()
20. {
21. Log.i(TAG,"服务成功启动...");
22. }
23. }

清单文件中配置服务:
1. <service android:name="com.example.service.MyService"></service>
当点击任务栏通知即开启服务:
\
logcat成功打印日志,服务启动成功:   \
3.PendingIntent配合SmsManger使用  下面使用SmsManager发送一条短信。
1. public void sendSMS()
2. {
3. SmsManager sm = SmsManager.getDefault();
4. PendingIntent sentIntent = PendingIntent.getBroadcast(this,0new Intent("com.xxx"),PendingIntent.FLAG_UPDATE_CURRENT);
5. sm.sendTextMessage("5556"null"hello world", sentIntent, null);
6. }
PendingIntent作为senTextMessage的参数被传递进来,作为短信发送成功的回执,此时PendingIntent会发送一个广播。还是以上面例子的广播接收者接收广播,可以看到logcat打印了日志:
\
另外5556也收到了短信:

上面基本把PendingIntent的使用场景都介绍了,api也使用了一些,其他api大家可以查文档。
### PendingIntent 中显式 Intent 与隐式 Intent区别及示例 #### 显式 Intent 的定义与使用 显式 Intent 是指在创建 `Intent` 时明确指定目标组件的类名,例如通过 `setClass()` 或 `setComponent()` 方法。这种方式直接告诉系统应该启动哪个组件,因此不会依赖系统进行匹配,确保 `Intent` 被准确发送到预期的目标组件[^3]。 示例代码如下: ```java Intent intent = new Intent(); intent.setComponent(new ComponentName("com.example.app", "com.example.app.TargetActivity")); PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE); ``` 在上述代码中,`PendingIntent` 封装了一个显式 `Intent`,其目标组件是 `com.example.app.TargetActivity`。这种方式适用于目标组件已知且固定的情况,具有较高的安全性准确性。 #### 隐式 Intent 的定义与使用 隐式 Intent 不指定具体的目标组件,而是通过 `action`、`category`、`data` 等属性描述要执行的操作,系统会根据 `IntentFilter` 匹配合适的组件来响应该 `Intent`。这种方式具有较高的灵活性,但也可能导致不确定性,因为多个组件可能匹配同一个 `Intent`[^3]。 示例代码如下: ```java Intent intent = new Intent("com.example.action.CUSTOM_ACTION"); intent.setPackage("com.example.app"); PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE); ``` 在上述代码中,`Intent` 的 `action` 为 `"com.example.action.CUSTOM_ACTION"`,并且通过 `setPackage()` 限制了目标组件只能在 `com.example.app` 包中查找。这种方式虽然仍为隐式 `Intent`,但通过限定包名,缩小了潜在的接收者范围,从而提高安全性。 #### 显式 Intent 与隐式 Intent区别 | 特性 | 显式 Intent | 隐式 Intent | |------|-------------|-------------| | **目标组件** | 明确指定组件名称 | 不指定具体组件,由系统匹配 | | **匹配机制** | 直接发送给指定组件 | 系统根据 `IntentFilter` 匹配 | | **适用场景** | 启动特定组件,如自身应用内的 `Activity` 或 `Service` | 启动未知组件,如调用系统功能或第三方服务 | | **安全性** | 高,不会被其他组件意外接收 | 相对较低,可能被多个组件匹配 | | **灵活性** | 低,必须明确知道目标组件 | 高,可适配多种组件 | #### PendingIntent 中使用显式与隐式 Intent 的注意事项 - **显式 Intent** 在 `PendingIntent` 中使用时,不需要额外设置 `package` 属性,因为目标组件已经明确指定。 - **隐式 Intent** 在 `PendingIntent` 中使用时,建议通过 `setPackage()` 限定目标包名,以避免被其他应用的组件接收[^2]。 - 从 Android 12 开始,创建 `PendingIntent` 时应使用 `FLAG_IMMUTABLE` 或 `FLAG_MUTABLE` 标志位,以控制 `Intent` 是否可以被修改,从而增强安全性。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值