适配Android S+时MediaButtonReceiver构建PendingIntent报错求助
问题场景
开发音频应用时,前台通知通过MediaButtonReceiver.buildMediaButtonPendingIntent()创建删除意图,适配Android 12及以上版本后触发崩溃,错误提示要求创建PendingIntent时必须指定FLAG_IMMUTABLE或FLAG_MUTABLE。
原崩溃触发代码片段:
val notificationBuilder = NotificationCompat.Builder(context) notificationBuilder.setContentTitle(description.title) notificationBuilder.setContentText(description.subtitle) notificationBuilder.setSubText(description.description) notificationBuilder.setContentIntent(pendingIntent) notificationBuilder.setAutoCancel(true) notificationBuilder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC) notificationBuilder.setDeleteIntent(MediaButtonReceiver.buildMediaButtonPendingIntent(context, PlaybackStateCompat.ACTION_STOP))
崩溃日志:
Caused by: java.lang.IllegalArgumentException: com.islambook: 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:375) at android.app.PendingIntent.getBroadcastAsUser(PendingIntent.java:645) at android.app.PendingIntent.getBroadcast(PendingIntent.java:632) at androidx.media.session.MediaButtonReceiver.buildMediaButtonPendingIntent(MediaButtonReceiver.java:274) at androidx.media.session.MediaButtonReceiver.buildMediaButtonPendingIntent(MediaButtonReceiver.java:234) at com.islambook.Audio.MediaStyleHelper.from(MediaStyleHelper.kt:42)
问题核心:旧版本androidx.media库的MediaButtonReceiver.buildMediaButtonPendingIntent()方法未针对API31+添加合规Flag,且该方法为系统类方法无法直接修改。
解决方案
方案1:升级AndroidX Media库(推荐)
将androidx.media:media依赖升级到1.4.0及以上版本(最新稳定版更佳),升级后库内部会自动在API31+环境下为PendingIntent添加FLAG_IMMUTABLE,原代码无需修改即可正常运行。
方案2:手动创建PendingIntent替代系统方法
如果暂时无法升级依赖库,可手动构建广播PendingIntent并自行指定Flag:
val notificationBuilder = NotificationCompat.Builder(context) // 保留原有通知配置 notificationBuilder.setContentTitle(description.title) notificationBuilder.setContentText(description.subtitle) notificationBuilder.setSubText(description.description) notificationBuilder.setContentIntent(pendingIntent) notificationBuilder.setAutoCancel(true) notificationBuilder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC) // 手动构建停止媒体动作的PendingIntent val stopMediaIntent = Intent(context, MediaButtonReceiver::class.java).apply { action = MediaButtonReceiver.ACTION_MEDIA_BUTTON putExtra( Intent.EXTRA_KEY_EVENT, KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_STOP) ) } val pendingStopIntent = PendingIntent.getBroadcast( context, 0, stopMediaIntent, // 根据API版本适配Flag,FLAG_UPDATE_CURRENT保持原有逻辑 PendingIntent.FLAG_UPDATE_CURRENT or if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) PendingIntent.FLAG_IMMUTABLE else 0 ) notificationBuilder.setDeleteIntent(pendingStopIntent)
注意事项
- 优先使用
FLAG_IMMUTABLE:媒体按钮控制的PendingIntent无需可变,符合官方安全实践;仅当需要支持内回复、气泡等特殊功能时才使用FLAG_MUTABLE。
内容的提问来源于stack exchange,提问作者Saif
相关产品推荐
相关产品推荐

