You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

适配Android S+时MediaButtonReceiver构建PendingIntent报错求助

Android 12+(API 31+)适配: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 06:25:17