[英]Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified
[英]MediaSessionCompat:Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent
我正在尝试将我的应用程序更新为 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 中看到的那样class。
// 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
你们知道我该如何解决这个错误吗?
如果您没有在任何地方使用PendingIntent
。 该问题可能会通过添加或更新此依赖项来解决
// required to avoid crash on Android 12 API 31
implementation 'androidx.work:work-runtime-ktx:2.7.0'
这解决了我的问题。
如果您没有在您的应用程序中使用待定意图,请尝试这个。 实现 'androidx.work:work-runtime-ktx:2.7.0'
否则如果您正在使用待处理的意图,则更改此
pendingIntent = PendingIntent.getActivity(
this,
0, intentToLaunchThisActivityFromNotification,
PendingIntent.FLAG_UPDATE_CURRENT);
至
`
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);
}`
对我来说,我必须升级
liteImplementation "com.google.android.gms:play-services-ads:20.4.0"
至
liteImplementation "com.google.android.gms:play-services-ads:20.6.0"
显然 play-services-ads:20.4.0 依赖于不支持 sdk 31 的工作运行时版本。
如果您的应用面向 Android 12,您必须指定您的应用创建的每个PendingIntent
对象的可变性。
在您的情况下, android.support.v4.media.session.MediaSessionCompat
负责在MediaSessionCompat
初始化期间创建PendingItent
。
解决方案:幸运的是, MediaSessionCompat
类有一个额外的@constructor
,因此我们可以将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)
}
源代码: https : //github.com/dautovicharis/issue-media-session-compat
更新:谢谢去:
在1.3.0版本中, MediaSessionCompat有新的变化,我们可以根据 TODO(b/182513352) 评论清楚地看到与 Android 12 相关的某些内容缺失。
在新的androidx.media:media:
发布之前,使用我提供的解决方法应该可以正常工作。
更新:我们希望TODO(b/182513352)将在即将发布的版本中得到修复。 在此之前,我们可以使用支持FLAG_IMMUTABLE
implementation "androidx.media:media:1.3.0-rc02
”。
解决了这个错误刚刚使用PendingIntent.FLAG_MUTABLE
for Android Version 12 OR 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);
}
implementation 'androidx.work:work-runtime:2.7.1'
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) { alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, PendingIntent.getBroadcast(getApplicationContext(), 0, alertIntent, PendingIntent.FLAG_MUTABLE)); } else { alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, PendingIntent.getBroadcast(getApplicationContext(), 0, alertIntent, PendingIntent.FLAG_UPDATE_CURRENT)); }
将以下行添加到您的build.gradle(app)
下的dependencies
。
dependencies {
// ...
implementation 'androidx.work:work-runtime:2.7.1'
}
如果您更新到至少 1.4.1 版本,现在应该修复此问题
https://developer.android.com/jetpack/androidx/releases/media#media-1.4.1
版本 1.4.1 2021 年 8 月 4 日
androidx.media:media:1.4.1 已发布。 1.4.1 版包含这些提交。
Bug修复
- 修复了创建 PendingIntent 的可变性标志,以防止在针对 Android S 时崩溃。
- 修复 NotificationCompat.MediaStyle 的 ClassVerificationFailure。
我将 SdkVersion 更改为 31 后更新了您的库,然后错误消失了
如果使用 java 或 react-native 然后将其粘贴到 app/build.gradle
dependencies {
// ...
implementation 'androidx.work:work-runtime:2.7.1'
}
如果使用 Kotlin,那么使用这个
dependencies {
// ...
implementation 'androidx.work:work-runtime-ktx:2.7.0'
}
使用 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);
}
如果有人仍然面临 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">
使用 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);
这对我有用->
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, REQUEST_CODE, intent, PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT);
我正在为 shedule 调用类使用 Flag mutable
alarmMgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmIntent = PendingIntent.getBroadcast(this, 0, new Intent(this, AlarmReceiver.class), PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT);
有时您只需要更新 Android studio 中的 Gradle 构建工具。 只需升级到最新版本即可解决导致我出现此问题的问题。
要更新到最新版本的 Gradle,只需单击显示在 Android Studio 右下角的小 Gradle 更新对话框。
要做两处改变
def work_version = "2.7.0"
// (Java only)
implementation "androidx.work:work-runtime:$work_version"
// Kotlin + coroutines
implementation "androidx.work:work-runtime-ktx:$work_version"
在创建未决意图时添加 FLAG_IMMUTABLE
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, FLAG_IMMUTABLE);
就我而言,原因是关于旧版本的 Chuck 库。
我把它从
implementation 'com.readystatesoftware.chuck:library:1.1.0'
到新的实施,如
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"
}
然后崩溃消失了。
请参阅文档: https ://github.com/ChuckerTeam/chucker
将 com.google.android.gms:play-services-analytics 依赖项的版本更新为 build.gradle 文件中的 18.0.1 解决了我遇到的问题。 在 Ionic 中,您还可以更改 config.xm 中的版本
<plugin name="cordova-plugin-google-analytics" spec="1.8.6">
<variable name="PLAY_SERVICES_VERSION" value="18.0.1" />
<variable name="GMS_VERSION" value="18.0.1" />
</plugin>
或删除并再次添加插件,为 PLAY_SERVICES_VERSION 和 GMS_VERSION 添加具有正确版本的参数。
另外请注意,如果您进行此更改,请确保将所有播放服务更改为相同版本(在我的情况下为 18.+),例如我使用 cordova-plugin-googleplus,因此您还应该更改此插件的 PLAY_SERVICES_VERSION 和在构建之后,所有这些都会在 build.gradle 文件中注入播放服务依赖项。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.