MediaSessionCompat:Targeting S+ (version 31 and above) 要求在创建 PendingIntent 时指定 FLAG_IMMUTABLE 或 FLAG_MUTABLE 之一

Ade*_*ino 5 java android android-mediaplayer kotlin android-studio

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

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

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

但我有以下错误

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
Run Code Online (Sandbox Code Playgroud)

我正在使用最新版本的媒体库(“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);
}

Run Code Online (Sandbox Code Playgroud)

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

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

and*_*2ag 362

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

    // required to avoid crash on Android 12 API 31
    implementation 'androidx.work:work-runtime-ktx:2.7.1'
Run Code Online (Sandbox Code Playgroud)

这解决了我的问题。

您可以./gradlew app:dependencies在项目的终端中执行,并发现哪些依赖项包括旧版本的工作运行时。然后您可以尝试升级该依赖项以努力做正确的事情

  • 您可以在项目的终端中执行“./gradlew app:dependencies”,并发现哪些依赖项包含旧版本的“work-runtime”。然后您可以尝试升级该依赖项以努力做正确的事情 (6认同)
  • 中奖答案!也解决了我的问题。看起来它已在 v-alpha-02 中修复:https://developer.android.com/jetpack/androidx/releases/work#2.7.0-alpha02 (4认同)

Noa*_*ram 145

解决了仅适用 PendingIntent.FLAG_MUTABLE于 Android 版本 12 或更高版本的此错误

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);
    }
Run Code Online (Sandbox Code Playgroud)

  • 哇!多么棒的解决方案啊!只有一个问题。您打算如何将其集成到 MediaSessionCompat 初始化中?你知道,就像问的问题一样。 (7认同)

Har*_* D. 40

PendingIntent如果您的应用面向 Android 12,则必须指定应用创建的每个对象的可变性。

在您的情况下,android.support.v4.media.session.MediaSessionCompat负责PendingItent在初始化期间创建MediaSessionCompat

解决方案:@constructor幸运的是,该类 有一个附加的MediaSessionCompat,因此我们可以pendingItent作为参数传递。如果我们为component参数传递 null,它将在库中初始化。

override fun onCreate() {
        super.onCreate()

        val mediaButtonIntent = Intent(Intent.ACTION_MEDIA_BUTTON)
        val pendingItent = PendingIntent.getBroadcast(
            baseContext,
            0, mediaButtonIntent,
            PendingIntent.FLAG_IMMUTABLE
        )

        mediaSession = MediaSessionCompat(baseContext, TAG, null, pendingItent).also {
            it.isActive = true
        }

        sessionToken = mediaSession.sessionToken
        packageValidator = PackageValidator(this@MediaService, R.xml.allowed_media_browser_callers)
    }
Run Code Online (Sandbox Code Playgroud)

源代码: https: //github.com/dautovicharis/issue-media-session-compat

更新:感谢转到:

在1.3.0版本中,MediaSessionCompat发生了新的变化,根据 TODO(b/182513352) 注释,我们可以清楚地看到缺少与 Android 12 相关的内容。

在新androidx.media:media:版本发布之前,使用我提供的解决方法应该可以正常工作。

更新:我们希望TODO(b/182513352)将在即将发布的版本中得到修复。在那之前,我们可以在支持的implementation "androidx.media:media:1.3.0-rc02地方使用“ FLAG_IMMUTABLE

  • 新版本“androidx.media:media:1.4.1”在 Android SDK 31 中可以正常工作 https://developer.android.com/jetpack/androidx/releases/media#version_141_3 (2认同)

iDe*_*ode 36

对于使用 Java 的用户:

将以下行添加到您的build.gradle(app)under dependencies.

dependencies {
  // ...
  implementation 'androidx.work:work-runtime:2.7.1'
}
Run Code Online (Sandbox Code Playgroud)


صلي*_*ouk 13

如果您没有在应用程序中使用挂起的意图,请尝试这个。实现 'androidx.work:work-runtime-ktx:2.7.0'

否则如果您正在使用挂起的意图,则更改此

pendingIntent = PendingIntent.getActivity(
                        this,
                        0, intentToLaunchThisActivityFromNotification,
                        PendingIntent.FLAG_UPDATE_CURRENT);
Run Code Online (Sandbox Code Playgroud)

到:

   if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
       pendingIntent = PendingIntent.getActivity(
                        this,
                        0, intentToLaunchThisActivityFromNotification,
                        PendingIntent.FLAG_IMMUTABLE);
   }
   else
   {
       pendingIntent = PendingIntent.getActivity(
                        this,
                        0, intentToLaunchThisActivityFromNotification,
                        PendingIntent.FLAG_UPDATE_CURRENT);
   }
Run Code Online (Sandbox Code Playgroud)

或对于 C#/Xamarin.Android:

   PendingIntent pendingIntent = null;
   if (Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.S)
   {
      pendingIntent = PendingIntent.GetActivity(mContext, 0, intent, PendingIntentFlags.Mutable);
   }
   else
   {
                        pendingIntent = PendingIntent.GetActivity(mContext, 0, intent, PendingIntentFlags.OneShot);
   }
Run Code Online (Sandbox Code Playgroud)


Mar*_*hat 12

如果使用 java 或 react-native,则将其粘贴到 app/build.gradle 中

dependencies {
  // ...
  implementation 'androidx.work:work-runtime:2.7.1'
}
Run Code Online (Sandbox Code Playgroud)

如果使用 Kotlin 那么使用这个

dependencies {
  // ...
  implementation 'androidx.work:work-runtime-ktx:2.7.0'
}
Run Code Online (Sandbox Code Playgroud)

使用 PendingIntent 时出错

if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {

 

               pendingIntent = PendingIntent.getActivity(
                        this,
                        0, intentToLaunchThisActivityFromNotification,
                        PendingIntent.FLAG_IMMUTABLE);
            }
            else
            {
                 pendingIntent = PendingIntent.getActivity(
                        this,
                        0, intentToLaunchThisActivityFromNotification,
                        PendingIntent.FLAG_UPDATE_CURRENT);
            }
Run Code Online (Sandbox Code Playgroud)

如果有人仍然面临 Android 12 的崩溃问题,请确保在 AndroidMenifest.xml 中添加以下内容

<activity 
   ...
   android:exported="true" // in most cases it is true but based on requirements it can be false also   
>   


   // If using react-native push notifications then make sure to add into it also

 <receiver   
android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationBootEventReceiver" android:exported="true">
 
   //  Similarly
 
 <service android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationListenerService" android:exported="true">
Run Code Online (Sandbox Code Playgroud)


Cod*_*ice 10

对我来说,我必须升级

    liteImplementation "com.google.android.gms:play-services-ads:20.4.0"
Run Code Online (Sandbox Code Playgroud)

    liteImplementation "com.google.android.gms:play-services-ads:20.6.0"
Run Code Online (Sandbox Code Playgroud)

显然 play-services-ads:20.4.0 依赖于不支持 sdk 31 的工作运行时版本。


Kun*_*war 9

这对我有用 ->

PendingIntent pendingIntent = PendingIntent.getBroadcast(context, REQUEST_CODE, intent, PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT);
Run Code Online (Sandbox Code Playgroud)

notification.java 中的更改

PendingIntent.FLAG_IMMUTABLE

100% 工作


Sho*_*omu 8

使用 Android 版本 12 或 S 升级应用程序目标,仅使用 PendingIntent.FLAG_MUTABLE 和 PendingIntent.FLAG_IMMUTABLE

int intentFlagType = PendingIntent.FLAG_ONE_SHOT;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
    intentFlagType = PendingIntent.FLAG_IMMUTABLE;  // or only use FLAG_MUTABLE >> if it needs to be used with inline replies or bubbles.
}
PendingIntent pendingIntent = PendingIntent.getActivity(context, notificationID, intent, intentFlagType);
Run Code Online (Sandbox Code Playgroud)


ogu*_*han 5

就我而言,原因是旧版本的 Chuck 库。

我已经把它从

implementation 'com.readystatesoftware.chuck:library:1.1.0'
Run Code Online (Sandbox Code Playgroud)

到新的实施,例如

dependencies {
  debugImplementation "com.github.chuckerteam.chucker:library:3.5.2"
  releaseImplementation "com.github.chuckerteam.chucker:library-no-op:3.5.2"
}

val client = OkHttpClient.Builder()
                .addInterceptor(ChuckerInterceptor(context))
                .build()


android {
  compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
  }

  // For Kotlin projects add also this line
  kotlinOptions.jvmTarget = "1.8"
}
Run Code Online (Sandbox Code Playgroud)

然后崩溃就消失了。

请参阅文档: https: //github.com/ChuckerTeam/chucker