如何解决android api 30+中的"Missing PendingIntent mutability flag"lint警告?
当我把目标SDK更新为30+(Android R或更高版本)时,当我想定义PendingIntent
时,在我的PendingIntent.FLAG_UPDATE_CURRENT
标志上出现了一个lint警告Missing PendingIntent mutability flag
。
我应该如何在不影响应用功能的情况下处理这个提示呢?
您可以将您的待定意向设置为
val updatedPendingIntent = PendingIntent.getActivity(
applicationContext,
NOTIFICATION_REQUEST_CODE,
updatedIntent,
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT // setting the mutability flag
)
根据这里的文档。https://developer.android.com/about/versions/12/behavior-changes-12#pending-intent-mutability
强烈考虑使用FLAG_IMMUTABLE,只有在某些功能依赖于PendingIntent是可变的情况下才使用FLAG_MUTABLE,例如,如果它需要与内联回复或气泡一起使用。
相应地选择你的旗帜。
如果你想阅读更多关于这方面的内容,我建议你在这里阅读这篇伟大的文章。https://medium.com/androiddevelopers/all-about-pendingintents-748c8eb8619
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT } else { PendingIntent.FLAG_UPDATE_CURRENT }
- user924 2021-09-30
如果你没有使用最新版本的WorkManager,你会看到这个问题。它已经在版本2.7.0-alpha02中得到了修复。
使PendingIntent的突变性显性化,以修复针对Android 12时的崩溃问题。
请记住,2.7.0-alpha02仅与Android 12 Developer Preview 1 SDK兼容。所以你可能想等到它进入测试版或RC版。
2021年4月21日更新 -- 为在谷歌上搜索该问题的人补充这个答案,你可能遇到的错误可能看起来像这样。
java.lang.IllegalArgumentException: com.myapp.myapp: Targeting S+ (version 10000 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:386)
at android.app.PendingIntent.getBroadcastAsUser(PendingIntent.java:657)
at android.app.PendingIntent.getBroadcast(PendingIntent.java:644)
at androidx.work.impl.utils.ForceStopRunnable.getPendingIntent(ForceStopRunnable.java:174)
at androidx.work.impl.utils.ForceStopRunnable.isForceStopped(ForceStopRunnable.java:108)
at androidx.work.impl.utils.ForceStopRunnable.run(ForceStopRunnable.java:86)
at androidx.work.impl.utils.SerialExecutor$Task.run(SerialExecutor.java:75)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:920)
您不必在您的应用程序中实际直接使用 WorkManager 就能看到这种崩溃。
正如此处所概述的解决方案,是在您的build.gradle
文件中添加一个用于Android 12构建的依赖项。
implementation 'androidx.work:work-runtime-ktx:2.7.0-alpha05'
请注意,无论你是只使用Java、Kotlin + coroutines、RxJava2、GCMNetworkManager等,这个依赖性都是不同的。所以一定要检查上面的dox。
显然,把上面的版本号换成最新的。如前所述,它与Android-13之前的版本不兼容。
-alpha04
,但仍然收到错误。我的应用程序只有一个PendingIntent,无法从这个崩溃中继续前进。第三方库会导致这种崩溃吗?
- Adam Gardner 2021-07-01
implementation "androidx.work:work-runtime:2.7.0-alpha05"
。它在java中工作得很好。
- satheesh 2021-08-18
PendingIntent
中使用了正确的标志,那么这就是你需要的解决方案。
- Khantahr 2021-11-03
如果你让你的应用程序在android 12中运行,有一个新的PendingIntent可变异标志。如果你不希望你的PendingIntent被变异,请使用
PendingIntent pendingIntent;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
pendingIntent = PendingIntent.getActivity(this,
0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
}else {
pendingIntent = PendingIntent.getActivity(this,
0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
}
如果你想让你的PendingIntent被突变,请使用下面的方法。
PendingIntent pendingIntent;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
pendingIntent = PendingIntent.getActivity(this,
0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
}else {
pendingIntent = PendingIntent.getActivity(this,
0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
}
在谷歌文档中说,强烈考虑使用FLAG_IMMUTABLE,只有在某些功能依赖于PendingIntent是可变的情况下才使用FLAG_MUTABLE。这个改变应该是直接的。 另外,如果你在你的应用程序中使用AdMob 20.4.0或更低版本,请确保你添加以下工作管理器依赖。
//Work Manager dependency
implementation 'androidx.work:work-runtime:2.7.1'
请注意,目前工作经理的依赖版本是2.7.1。如果你愿意,你可以把版本更新到最新的版本。
FLAG_MUTABLE
是的,它应该是S
,因为它是在SDK31中添加的,FLAG_INMUTABLE
是在SDK23中添加的,所以M是可以的。
- jcesarmobile 2022-02-04
else
块中出现"Missing PendingIntent mutability flag" linter警告。我们可以@SuppressLint("UnspecifiedImmutableFlag")
,但似乎linter应该知道这个代码分支,不是吗?有什么更好的办法来解决这个警告吗?
- ksparrow 2022-06-07
如果你的应用程序以Android 12(targetSdkVersion = 31)
为目标,并且直接使用旧版本的WorkManager或通过任何第三方库,那么你需要将其更新到最新的来解决这个问题。
dependencies {
val work_version = "2.7.1"
// (Java only)
implementation("androidx.work:work-runtime:$work_version")
// Kotlin + coroutines
implementation("androidx.work:work-runtime-ktx:$work_version")
// optional - RxJava2 support
implementation("androidx.work:work-rxjava2:$work_version")
}
final int flag = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE : PendingIntent.FLAG_UPDATE_CURRENT;
PendingIntent pendingIntent = PendingIntent.getActivity(context, PENDING_INTENT_REQUEST_CODE, notificationIntent, flag);
如果你使用Java和ADMOB,你会在SDK S或Android 12上遇到PendingIntent错误。这里有一个修正,以便ADMOB使用正确的工作运行时间。
implementation 'com.google.android.gms:play-services-ads:19.5.0'
constraints {
implementation('androidx.work:work-runtime:2.7.0-alpha05') {
because 'previous versions have a bug impacting this application'
}
}
play-services-ads:20.4.0
版本开始就被修复了,因为发行说明中说developers.google.com/admob/android/rel-notes。
- ilansas 2021-12-29
在我的案例中,这也是由使用旧的WorkManager版本的第三方库造成的,为了在所有的依赖中强制使用新的Android Work版本,请在你的root build.gradle文件中使用这个。
allproject {
project.configurations.all {
resolutionStrategy {
force 'androidx.work:work-runtime:2.7.0'
}
}
}
这个崩溃问题通过 : 实现 'androidx.work:work-runtime:2.7.1' 得到了解决。
如果你让你的应用程序在android 12中运行,有一个新的PendingIntent mutability标志。如果你不希望你的PendingIntent被突变,请使用
爪哇岛
PendingIntent updatedPendingIntent = PendingIntent.getActivity(
applicationContext,
NOTIFICATION_REQUEST_CODE,
updatedIntent,
PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT // setting the mutability flag
)
科特林
val updatedPendingIntent = PendingIntent.getActivity(
applicationContext,
NOTIFICATION_REQUEST_CODE,
updatedIntent,
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT // setting the mutability flag
)
如果你希望你的PendingIntent是静音的,请使用以下方法。
爪哇岛
PendingIntent updatedPendingIntent = PendingIntent.getActivity(
applicationContext,
NOTIFICATION_REQUEST_CODE,
updatedIntent,
PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT // setting the mutability flag
)
科特林
val updatedPendingIntent = PendingIntent.getActivity(
applicationContext,
NOTIFICATION_REQUEST_CODE,
updatedIntent,
PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT // setting the mutability flag
)
在最后实施这一依赖性的过程中
//Work Manager dependency
implementation 'androidx.work:work-runtime:2.7.1'
由于我的代码中有四个不同的PendingIntents,我开始在所有这些PendingIntents中添加FLAG_IMMUTABLE。在花了很多时间分析了我的4个Intents之后,我突然意识到问题可能来自我的一个库。
在build.gradle中,库通常在旧时被高亮显示,但对于Firebase BOM来说,情况并非如此。
我有过。
implementation platform('com.google.firebase:firebase-bom:26.1.1')
事实证明,这是非常古老的。在更新到
implementation platform('com.google.firebase:firebase-bom:29.0.4')
一切都很好。不再有FLAG_IMMUTABLE错误
我有过像Fatal Exception: java.lang.IllegalArgumentException. Not posted. PendingIntents attached to actions with remote inputs must be mutable
这样的崩溃。
我写了这个util方法,它允许将可变性作为一个参数发送。有时它需要获得可变标记,例如通知中的reply actions。
private fun getPendingIntentFlags(isMutable: Boolean = false) =
when {
isMutable && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S ->
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE
!isMutable && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ->
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
else -> PendingIntent.FLAG_UPDATE_CURRENT
}
使用实例。
val quickReplyPendingIntent = PendingIntent.getBroadcast(
context, notificationId, replyIntent,
getPendingIntentFlags(true)
)
这是工作库的问题,即使是最新的版本也受到了影响 2.7.0-alpha04
https://issuetracker.google.com/issues/194108978
作为临时的解决方法--在gradle中注释掉包括"work"的依赖,并通过项目删除使用该类。至少在这种方式下,你可以正常运行应用程序,并在其他功能和领域工作....。
在我的项目中,这句话起作用了
PendingIntent pendingIntent = PendingIntent.getActivity(this,0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
这个问题是在你升级你的项目并以安卓12版为目标时出现的,安卓在安卓12上运行应用程序。解决办法是,你可以更新你的所有待定实习生。
针对S+(版本31及以上),在创建PendingIntent 时,需要指定FLAG_IMMUTABLE或FLAG_MUTABLE中的一个。
下面使用的是代码
PendingIntent pendingIntent = null;
if (Build.VERSION.SDK_INT>= Build.VERSION_CODES.S){
pendingIntent = stackBuilder.getPendingIntent(1, PendingIntent.FLAG_MUTABLE);
}else {
pendingIntent = stackBuilder.getPendingIntent(1, PendingIntent.FLAG_UPDATE_CURRENT);
}
如果你在你的项目中使用一个接收器,也要实现这个依赖性工作
//Work Manager dependency
implementation 'androidx.work:work-runtime:2.7.1'
我把我的work-runtime-ktx
版本更新到了2.7.1
在做了上述改变之后,我又遇到了一个错误
java.lang.IllegalStateException: SimpleTypeImpl should not be created for error type: ErrorScope{Error scope for class <ERROR CLASS> with arguments: org.jetbrains.kotlin.types.IndexedParametersSubstitution@14ac19e7}
看看我是如何通过更新kotlin-gradle-plugin
版本这里来解决上述错误的。
这是我的用例,在KOTLIN中从30到33移动。
1.添加媒体依赖性
implementation "androidx.media:media:1.4.1"
2.更新工作经理
implementation "androidx.work:work-runtime-ktx:2.7.0"
3.更新不可变的
fun getImmutableFlag() = if(isAndroidAPI31()) PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT else 0
fun isAndroidAPI31() = android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S
private fun createOpenAppIntent(context: Context): PendingIntent {
val intent = Intent(context, MainActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
}
return PendingIntent.getActivity(context, 0, intent, getImmutableFlag())
}
4.如果在所有活动、服务、提供者、接受者中没有添加出口标签,则在清单中添加出口标签。
android:exported="true"
希望这能起作用,祝你有个好心情。
你可以像这样更新待定的意向。
val updatedPendingIntent = PendingIntent.getActivity(
context,
NOTIFICATION_REQUEST_CODE,
updatedIntent,
PendingIntent.FLAG_IMMUTABLE| PendingIntent.FLAG_UPDATE_CURRENT
)
你可以将PendingIntent.FLAG_IMMUTABLE与|号一起加入,这样就可以工作了。