Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified

    最近将 Android 项目的 targetSdk 的版本号由 30 升到了 31,在真机(系统版本>=12)上运行的过程中报出了如下错误:

java.lang.IllegalArgumentException: <...your package examp...>: Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent.
Strongly consider using FLAG_IMMUTABLE, only use FLAG_MUTABLE if some functionality depends on the PendingIntent being mutable, e.g. if it needs to be used with inline replies or bubbles.

    查看报错日志,最后定位到一处报错的代码:

PendingIntent pi_pr = PendingIntent.getBroadcast(this, 101, intent_pre, 0);

    笔者定义了一个 PendingIntent,最终生成一个Notification. 报错是因为上面的方法,第四个参数(int flags)传了一个 0 值。

    以下是对SDK文档对参数 flags 的解释:

flags – May be FLAG_ONE_SHOT, FLAG_NO_CREATE, FLAG_CANCEL_CURRENT, FLAG_UPDATE_CURRENT, FLAG_IMMUTABLE or any of the flags as supported by Intent.fillIn() to control which unspecified parts of the intent that can be supplied when the actual send happens.

    通常这个值为上面注释里面提到的这些值<FLAG_ONE_SHOT, FLAG_NO_CREATE, FLAG_CANCEL_CURRENT, FLAG_UPDATE_CURRENT, FLAG_IMMUTABLE>,这里笔者传入 0 表示不使用 flags 进行创建PendingIntent时的控制。

    以下节选的是部分 SDK 文档对 flags 值的解释:

Starting with Build.VERSION_CODES.S, it will be required to explicitly specify the mutability of PendingIntents on creation with either (@link #FLAG_IMMUTABLE} or FLAG_MUTABLE. It is strongly recommended to use FLAG_IMMUTABLE when creating a PendingIntent. FLAG_MUTABLE should only be used when some functionality relies on modifying the underlying intent, e.g. any PendingIntent that needs to be used with inline reply or bubbles.

    上面这段话的意思是说,从版本Build.VERSION_CODES.S(31)开始,flags 值必须显式的声明为 FLAG_IMMUTABLE 或 FLAG_MUTABLE,但是通常是建议设置为 FLAG_IMMUTABLE

    所以从报错提示信息以及上面注释内容,可以得到的解决方案是:

    方式一:将该值设置为:FLAG_IMMUTABLE 即可。

PendingIntent pi_pr = PendingIntent.getBroadcast(this, 101, intent_pre, PendingIntent.FLAG_IMMUTABLE);

   如果你想保留之前旧版本的实现,可以对版本进行判断然后分别处理:

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

    方式二:将项目的 targetSdk 降到 31 以下。

其他参考内容:

1. Android中PendingIntent的使用
https://blog.csdn.net/xiaokangss/article/details/133364589

2. 构造PendingIntent时第四个参数flags的设置以及在Notification中的不同作用
https://blog.csdn.net/piglite/article/details/46581789

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

思涛的博客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值