MediaSessionCompat:Targeting S(版本 31 及以上)要求在创建 PendingIntent 时指定 FLAG_IMMUTABLE 或 FLAG_MUTABLE 之一

新手上路,请多包涵

我正在尝试将我的应用程序更新到 Android SDK 31,但我遇到了 MediaSessionCompat 问题。

我有一个扩展 MediaBrowserServiceCompat() 的 MediaService,在该服务的 onCreate 方法中我初始化了 MediaSessionCompat。

 override fun onCreate() {
  super.onCreate()
  mediaSession = MediaSessionCompat(this, TAG).apply {
    setCallback(mediaSessionCallback)
    isActive = true
  }
...

但我有以下错误

java.lang.RuntimeException: Unable to create service com.radio.core.service.MediaService: java.lang.IllegalArgumentException: com.xxx.xxx: 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.ActivityThread.handleCreateService(ActivityThread.java:4498)
        at android.app.ActivityThread.access$1500(ActivityThread.java:250)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2064)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loopOnce(Looper.java:201)
        at android.os.Looper.loop(Looper.java:288)
        at android.app.ActivityThread.main(ActivityThread.java:7829)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:982)
     Caused by: java.lang.IllegalArgumentException: com.xxx.xxx: 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 android.support.v4.media.session.MediaSessionCompat.<init>(MediaSessionCompat.java:567)
        at android.support.v4.media.session.MediaSessionCompat.<init>(MediaSessionCompat.java:537)
        at android.support.v4.media.session.MediaSessionCompat.<init>(MediaSessionCompat.java:501)
        at android.support.v4.media.session.MediaSessionCompat.<init>(MediaSessionCompat.java:475)
        at com.radio.core.service.MediaService.onCreate(MediaService.kt:63)
        at android.app.ActivityThread.handleCreateService(ActivityThread.java:4485)
            ... 9 more

我正在使用最新版本的媒体库(“androidx.media:media:1.4.0”),它能够处理来自 Andriod“S”的这一要求。正如在 MediaSessionCompact.java 中看到的那样班级。


// TODO(b/182513352): Use PendingIntent.FLAG_MUTABLE instead from S.
/**
 * @hide
 */
@RestrictTo(LIBRARY)
public static final int PENDING_INTENT_FLAG_MUTABLE =
  Build.VERSION.CODENAME.equals("S") ? 0x02000000 : 0;

...

if (mbrComponent != null && mbrIntent == null) {
  // construct a PendingIntent for the media button
  Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
  // the associated intent will be handled by the component being registered
  mediaButtonIntent.setComponent(mbrComponent);
  mbrIntent = PendingIntent.getBroadcast(context,
    0/* requestCode, ignored */, mediaButtonIntent,
    PENDING_INTENT_FLAG_MUTABLE);
}

演示问题的源代码 - https://github.com/adelinolobao/issue-media-session-compat

你们知道我该如何解决这个错误吗?

原文由 Adelino 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 970
2 个回答

如果您不在任何地方使用 PendingIntent 。可以通过添加或更新此依赖项来解决该问题

    // required to avoid crash on Android 12 API 31
    implementation 'androidx.work:work-runtime-ktx:2.7.0'

这解决了我的问题。

原文由 andrey2ag 发布,翻译遵循 CC BY-SA 4.0 许可协议

解决了这个错误 刚刚使用 PendingIntent.FLAG_MUTABLE 适用于 Android 版本 12 或 S

 PendingIntent pendingIntent = null;
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
        pendingIntent = PendingIntent.getActivity
               (this, 0, notificationIntent, PendingIntent.FLAG_MUTABLE);
    }
    else
    {
         pendingIntent = PendingIntent.getActivity
                (this, 0, notificationIntent, PendingIntent.FLAG_ONE_SHOT);
    }

原文由 Noaman Akram 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题