Android 12.0 通知--PendingIntent基本代码

一. PendingIntent 在 Android 通知中的使用场景

使用场景: Android 通知的 setContentIntent() 需要传入 PendingIntent , 即当点击通知时,执行 intent 的动作.如下例子:

//1.创建Intent对象

Intent intent = new Intent(this, MainActivity1.class);

//2.获取能启动 Activity 的PendingIntent 对象

PendingIntent pendingIntent = PendingIntent.getActivity(MainActivity.this, 0, intent, PendingIntent.FLAG_MUTABLE);

复制代码
PendingIntent pendingIntent = PendingIntent.getService(this,0,intent1,PendingIntent.FLAG_IMMUTABLE);

在android开发中,当创建一个Pendingintent时 ,你想要使用Targeting S+ (版本31及以上)的功能,就需要在创建PendingInten时指定

FLAG_IMMUtable或FLAG_MUTABLE之一。

"java.lang.IllegalArgumentException: com.example.imdemo: Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent."

PendingIntent.FLAG_IMMUTABLE:

Android 12(API 级别 31) 开始,Android系统引入了新的安全性和隐私性改进。》

解决:添加版本判断

不仅需要在四大组件添加 android:exported="true"

而且还需要在使用的PendingIntent处添加flag

基本改法一:

PendingIntent pendingIntent ;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
pendingIntent = PendingIntent.getActivity(ControlActivity.this, 0, intent, PendingIntent.FLAG_IMMUTABLE);
}else {
pendingIntent = PendingIntent.getActivity(ControlActivity.this, 0, intent, 0);

//pendingIntent = PendingIntent.getActivity(this, 123, intent, PendingIntent.FLAG_ONE_SHOT);
}

基本改法二:

if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
mPendingPollIntent = PendingIntent.getBroadcast(mContext, POLL_REQUEST, pollIntent, PendingIntent.FLAG_IMMUTABLE);
}else{
mPendingPollIntent = PendingIntent.getBroadcast(mContext, POLL_REQUEST, pollIntent, 0);
}

3.调用NotificationCompat.Builder

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "channel_id")
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("Notification Title")
.setContentText("Notification content text...")
.setContentIntent(pendingIntent) //2.设置PendingIntent
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
NotificationManager notificationManager = (NotificationManager.class);
NotificationChannel channel = new NotificationChannel("11", "channel-name", NotificationManager.IMPORTANCE_DEFAULT);
notificationManager.createNotificationChannel(channel);
notificationManager.notify(11, builder.build());

二. PendingIntent 的使用

**(1) PendingIntent 的获取
核心源码路径 : frameworks/base/core/java/android/app/PendingIntent.java

  1. 跳转到 Activity ,指定一个 Activity
    public static PendingIntent getActivity(Context context, int requestCode,
    Intent intent, @Flags int flags)
  2. 跳转到 Activity , 指定多各 Activity
    public static PendingIntent getActivities(Context context, int requestCode,
    @NonNull Intent[] intents, @Flags int flags)
  3. 打开 广播 组件
    public static PendingIntent getBroadcast(Context context, int requestCode,
    @NonNull Intent intent, @Flags int flags)
  4. 打开 服务 组件
    public static PendingIntent getService(Context context, int requestCode,
    @NonNull Intent intent, @Flags int flags)**

PendingIntent.getActivity(Context, int, Intent, int):启动活动

PendingIntent.getActivities(Context, int, Intent[], int):启动多个活动,意图中为数组

PendingIntent.getBroadcast(Context, int, Intent, int):启动广播

PendingIntent.getService(Context, int, Intent, int):启动服务

(2) 参数说明:

**context上下文:PendingIntent启动活动的上下文
requestCode : 发送方设定的请求码.
intent : 要启动的意图.(注意: 需要使用显示 Intent , 即明确将要启动的组件名).
flags : 主要是方便后续管理所有的PendingIntent对象,可选的标签如下:

  1. FLAG_ONE_SHOT : PendingIntent 只能使用一次.该标签后面还能说明.**

2) FLAG_NO_CREATE : 不创建 PendingIntent, 如果PendingIntent存在,则返回null.

3) FLAG_CANCEL_CURRENT : 如果所描述 PendingIntent 已存在,则在生成新的 PendingIntent 之前,取消当前已存在的PendingIntent.

4) FLAG_UPDATE_CURRENT : 如果所描述 PendingIntent 已存在,则保留该对象,并用新的数据更新该对象.

5) FLAG_IMMUTABLE : PendingIntent 不可变.

6) FLAG_MUTABLE : PendingIntent 可变.

三. PendingIntent 的实际应用场景

  1. 通知,在点击通知时执行调起本应用的操作,当然也可以执行其他操作
  2. 闹钟,定时执行某个操作
  3. 桌面小部件,点击小部件时执行某个操作 等等

这个要求的目的是增强应用的安全性,通过明确指定PendingIntent的可变性,可以减少安全漏洞,特别是在跨应用通信时。

在Android 12及以上版本中,如果创建PendingIntent时没有指定 FLAG_IMMUTABLE或FLAG_MUTABLE,应用将抛出异常并崩溃 。这是因为系统无法确定PendingIntent的预期用途和行为,从而无法确保其安全性。FLAG_IMMUTABLE通常是最安全的选择,适用于绝大多数情况。

四。另外一种发送通知的完整代码:

复制代码
     // 创建通知对象
        Notification notification = new Notification();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel("notify_im", "系统通知", NotificationManager.IMPORTANCE_LOW);
            channel.setSound(null, null);
            channel.enableVibration(false);
            manager.createNotificationChannel(channel);
            notification = new Notification.Builder(context.getApplicationContext(), "notify_im").setOnlyAlertOnce(true).setAutoCancel(true).build();
        }
        // 设置显示时间
        notification.when = System.currentTimeMillis();
        // 设置通知显示的图标
        notification.icon = R.mipmap.im_logo;
        // 设置通知的特性: 通知被点击后,自动消失
        notification.flags = Notification.FLAG_AUTO_CANCEL;
        notification.sound = null;
        notification.defaults = Notification.DEFAULT_LIGHTS;
        // 设置通知的显示视图
        notification.contentView = new RemoteViews(context.getPackageName(),R.layout.notification_im);
        notification.contentView.setTextViewText(R.id.tv_title,isGroup?"您有新的群消息":"收到来自"+nickName+"的新消息");
        notification.contentView.setImageViewResource(R.id.iv_logo,R.mipmap.im_logo);
        //设置跳转界面意图
        int flag = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S?PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT:PendingIntent.FLAG_UPDATE_CURRENT;
        notification.contentIntent =PendingIntent.getActivity(context, 0, intent, flag);
 
        // 发出通知
        manager.notify(notificationId, notification);
相关推荐
遗憾随她而去.18 小时前
Webpack5 基础篇(二)
前端·webpack·node.js
Mintopia18 小时前
🧭 一、全栈能力的重心正在从“实现” → “指令 + 验证”转移
前端·人工智能·全栈
xiaolyuh12318 小时前
ThreadLocalMap 中弱引用被 GC 后的行为机制解析
java·jvm·redis
Mintopia18 小时前
2025,我的「Vibe Coding」时刻
前端·人工智能·aigc
不知疲倦的仄仄18 小时前
第一天:从 ByteBuffer 内存模型到网络粘包处理实战
java·网络·nio
Tinachen8818 小时前
YonBIP旗舰版本地开发环境搭建教程
java·开发语言·oracle·eclipse·前端框架
西凉的悲伤19 小时前
html制作太阳系行星运行轨道演示动画
前端·javascript·html·行星运行轨道演示动画
星火开发设计19 小时前
堆排序原理与C++实现详解
java·数据结构·c++·学习·算法·排序算法
C_心欲无痕19 小时前
网络相关 - http1.1 与 http2
前端·网络
一只爱吃糖的小羊19 小时前
Web Worker 性能优化实战:将计算密集型逻辑从主线程剥离的正确姿势
前端·性能优化