Android 13 下使用 Parse SDK 崩溃:创建PendingIntent需指定IMMUTABLE/MUTABLE标志
ParseGCM.register() 触发 PendingIntent 异常的解决方案 你的应用基于Android版Parse SDK和GCM实现数据库变更通知,在onCreate()中调用ParseGCM.register(context)时,Android 13(API 31+)设备会触发如下RuntimeException:
Caused by: java.lang.IllegalArgumentException: com.myapp: 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.
at android.app.PendingIntent.checkFlags(PendingIntent.java:401)
at android.app.PendingIntent.getBroadcastAsUser(PendingIntent.java:671)
at android.app.PendingIntent.getBroadcast(PendingIntent.java:658)
at com.firebase.jobdispatcher.GooglePlayDriver.(GooglePlayDriver.java:72)
at com.parse.gcm.ParseGCM.register(ParseGCM.java:39)
该问题仅出现在Android 13及以上设备,核心原因是Android 13强制要求创建PendingIntent时必须指定FLAG_IMMUTABLE或FLAG_MUTABLE,但旧版本的Parse GCM SDK依赖的Firebase Job Dispatcher未处理该要求。
方案1:升级依赖库(优先推荐)
- 升级Parse Android SDK到支持Android 13的最新版本,新版本已修复该PendingIntent Flag问题。修改Module级
build.gradle中的依赖:
implementation 'com.parse:parse-android:1.21.0' // 替换为最新兼容版本 implementation 'com.parse:parse-gcm:1.21.0'
- 同步升级Firebase Job Dispatcher到支持API 31的版本:
implementation 'com.firebase:firebase-jobdispatcher:0.8.6'
方案2:手动指定PendingIntent Flag(无法升级SDK时使用)
如果无法升级SDK,可通过自定义子类的方式,在创建PendingIntent时添加FLAG_IMMUTABLE:
- 创建自定义
GooglePlayDriver子类,重写回调Intent创建逻辑:
public class CustomGooglePlayDriver extends GooglePlayDriver { public CustomGooglePlayDriver(Context context) { super(context); } @Override protected PendingIntent createCallbackIntent() { Intent intent = new Intent(FirebaseJobDispatcher.ACTION_EXECUTE); intent.setPackage(getContext().getPackageName()); intent.putExtra(FirebaseJobDispatcher.EXTRA_JOB, getJob()); // 添加FLAG_IMMUTABLE满足Android 13要求 return PendingIntent.getBroadcast(getContext(), 0, intent, PendingIntent.FLAG_IMMUTABLE); } }
- 修改ParseGCM的调用逻辑,替换默认的
GooglePlayDriver为自定义实现(需结合反射或SDK源码调整)
方案3:迁移到FCM替代GCM
GCM已被Firebase Cloud Messaging(FCM)正式取代,Parse官方也推荐使用FCM进行推送集成:
- 移除原GCM相关依赖,添加Parse FCM依赖:
implementation 'com.parse:parse-fcm:1.21.0'
- 替换原
ParseGCM.register()的调用为FCM的注册逻辑,按Parse官方文档完成配置。
内容的提问来源于stack exchange,提问作者matdev

