Android S+创建PendingIntent需指定FLAG_IMMUTABLE/MUTABLE报错解决
Android 12+ PendingIntent创建崩溃修复方案
问题表现
- 应用Target SDK ≥ 31(Android 12及以上)时,启动页面直接触发崩溃
- 崩溃核心报错:
java.lang.IllegalArgumentException: 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.
- 已添加
implementation 'androidx.work:work-runtime-ktx:2.7.1'依赖后问题未解决
根因分析
添加work-runtime依赖仅能修复AndroidX Work库内部旧版PendingIntent实现的兼容问题,崩溃实际是业务代码未符合Android 12新要求导致的。
从崩溃栈可以定位到问题出在BlankViewModel的init初始化块中,两处PendingIntent.getBroadcast调用都只传了旧版标志位,没有按系统要求指定可变性标志:
- 第一处判断闹钟是否已存在的调用,仅传入
PendingIntent.FLAG_NO_CREATE - 第二处创建闹钟触发用PendingIntent的调用,仅传入
PendingIntent.FLAG_UPDATE_CURRENT
修复步骤
当前场景下PendingIntent用于AlarmManager触发广播,不需要内联回复、气泡这类需要动态修改Intent附加数据的能力,按照官方推荐优先使用FLAG_IMMUTABLE即可。该标志在Android 12以下版本会被系统自动忽略,无需额外做版本判断。
修改init块中的两处PendingIntent创建代码:
- 修改闹钟状态判断逻辑:
_alarmOn.value = PendingIntent.getBroadcast( getApplication(), REQUEST_CODE, notifyIntent, PendingIntent.FLAG_NO_CREATE or PendingIntent.FLAG_IMMUTABLE ) != null
- 修改广播PendingIntent创建逻辑:
notifyPendingIntent = PendingIntent.getBroadcast( getApplication(), REQUEST_CODE, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE )
注意:如果后续需要实现通知内联回复、悬浮气泡这类需要动态更新PendingIntent数据的功能,再将
FLAG_IMMUTABLE替换为FLAG_MUTABLE即可,普通场景使用IMMUTABLE安全性更高。
通用排查思路
- 遇到该类崩溃首先看崩溃栈指向的代码位置:如果指向自己编写的业务代码,直接给对应PendingIntent添加符合要求的可变性标志即可
- 如果崩溃栈指向第三方库/AndroidX组件内部代码,再对应升级相关依赖到适配Android 12的版本
- 可变性标志选择优先级:优先用
FLAG_IMMUTABLE,仅在功能明确依赖可变PendingIntent时才使用FLAG_MUTABLE
内容的提问来源于stack exchange,提问作者Shiva s
相关产品推荐
相关产品推荐

