如何解决 android api 30+ 中的 "Missing PendingIntent mutability flag" lint 警告?
How to resolve "Missing PendingIntent mutability flag" lint warning in android api 30+?
一旦我将目标 SDK 更新为 30+(Android R 或更高版本),一个 lint 警告当我想定义 PendingIntent
.
时,Missing PendingIntent mutability flag
出现在我的 PendingIntent.FLAG_UPDATE_CURRENT
标志上
我应该如何处理这个 lint 而不影响应用程序的功能?
您可以将待定意向设置为
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
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.
相应地选择你的标志。
如果您想了解更多相关信息,我建议您阅读这篇很棒的文章:https://medium.com/androiddevelopers/all-about-pendingintents-748c8eb8619
如果您使用的不是最新版本的 WorkManager,就会遇到此问题。它已在版本 2.7.0-alpha02:
中修复
Make PendingIntent mutability explicit, to fix a crash when targeting 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 就会看到此崩溃。
如 here 所述,解决方案是为 Android 12 个构建向 build.gradle
文件添加依赖项:
implementation 'androidx.work:work-runtime-ktx:2.7.0-alpha05'
请注意,无论您仅使用 Java、Kotlin + coroutines、RxJava2、GCMNetworkManager 等,此依赖项都是不同的。因此请务必检查 dox以上.
很明显把上面的版本号换成最新的。如前所述,它与 android-13 之前的版本不兼容。
这是 Work 库的问题。
即使是最新版本也受到影响 2.7.0-alpha04
https://issuetracker.google.com/issues/194108978
作为临时解决方法 - 在 gradle 中注释掉包括“工作”依赖项,并删除在项目中使用该 class。至少通过这种方式,您可以 运行 正常应用并处理其他功能和领域....
如果您使用 Java 和 ADMOB,您会遇到 SDK S 或 Android12 的 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'
}
}
在我的例子中,它也是由使用旧 WorkManager 版本的第三方库强制使用新的 Android 工作版本在所有依赖项中使用它在你的 root build.gradle 文件:
allproject {
project.configurations.all {
resolutionStrategy {
force 'androidx.work:work-runtime:2.7.0'
}
}
}
如果您让您的应用在 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);
}
在 Google 文档中说,强烈考虑使用 FLAG_IMMUTABLE,仅当某些功能依赖于可变的 PendingIntent 时才使用 FLAG_MUTABLE。更改应该很简单。
此外,如果您在应用中使用 AdMob 20.4.0 或更低版本,请确保添加以下工作管理器依赖项:
//Work Manager dependency
implementation 'androidx.work:work-runtime:2.7.1'
请注意,当前工作管理器依赖版本为 2.7.1。如果需要,可以更新版本到最新版本。
此崩溃已通过以下方式解决:实施 '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
版本 .
来解决上述错误的
因为我的代码中有四个不同的 PendingIntents,所以我首先向所有这些添加 FLAG_IMMUTABLE。然而问题依然存在。
在花了很多时间分析我的 4 个意图之后,我突然意识到问题可能来自我的一个库。
在 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 个错误
如果您的应用面向 Android12(targetSdkVersion = 31)
,并且使用旧版本的WorkManager 直接或 通过任何 third-party 库 然后你需要 将它更新到最新的 来解决它。
dependencies {
def work_version = "2.7.1"
// (Java only)
implementation "androidx.work:work-runtime:$work_version"
// Kotlin + coroutines
implementation "androidx.work:work-runtime-ktx:$work_version"
}
对于 Java 开发者
PendingIntent pendingIntent = PendingIntent.getActivity(context, PENDING_INTENT_REQUEST_CODE,
notificationIntent,
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ?
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE : PendingIntent.FLAG_UPDATE_CURRENT);
我遇到过像 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)
)
如果您让您的应用在 android 12 中达到 运行,则有一个新的 PendingIntent 可变性标志。如果您不想让 PendingIntent 静音,请使用
Java
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 静音,请使用以下命令:
Java
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'
在我的项目中这条线有效
PendingIntent pendingIntent = PendingIntent.getActivity(this,0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
当您升级您的项目并针对 android 版本 12,Android 运行 应用程序在 Android 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'
一旦我将目标 SDK 更新为 30+(Android R 或更高版本),一个 lint 警告当我想定义 PendingIntent
.
Missing PendingIntent mutability flag
出现在我的 PendingIntent.FLAG_UPDATE_CURRENT
标志上
我应该如何处理这个 lint 而不影响应用程序的功能?
您可以将待定意向设置为
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
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.
相应地选择你的标志。
如果您想了解更多相关信息,我建议您阅读这篇很棒的文章:https://medium.com/androiddevelopers/all-about-pendingintents-748c8eb8619
如果您使用的不是最新版本的 WorkManager,就会遇到此问题。它已在版本 2.7.0-alpha02:
中修复Make PendingIntent mutability explicit, to fix a crash when targeting 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 就会看到此崩溃。
如 here 所述,解决方案是为 Android 12 个构建向 build.gradle
文件添加依赖项:
implementation 'androidx.work:work-runtime-ktx:2.7.0-alpha05'
请注意,无论您仅使用 Java、Kotlin + coroutines、RxJava2、GCMNetworkManager 等,此依赖项都是不同的。因此请务必检查 dox以上.
很明显把上面的版本号换成最新的。如前所述,它与 android-13 之前的版本不兼容。
这是 Work 库的问题。 即使是最新版本也受到影响 2.7.0-alpha04
https://issuetracker.google.com/issues/194108978
作为临时解决方法 - 在 gradle 中注释掉包括“工作”依赖项,并删除在项目中使用该 class。至少通过这种方式,您可以 运行 正常应用并处理其他功能和领域....
如果您使用 Java 和 ADMOB,您会遇到 SDK S 或 Android12 的 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'
}
}
在我的例子中,它也是由使用旧 WorkManager 版本的第三方库强制使用新的 Android 工作版本在所有依赖项中使用它在你的 root build.gradle 文件:
allproject {
project.configurations.all {
resolutionStrategy {
force 'androidx.work:work-runtime:2.7.0'
}
}
}
如果您让您的应用在 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);
}
在 Google 文档中说,强烈考虑使用 FLAG_IMMUTABLE,仅当某些功能依赖于可变的 PendingIntent 时才使用 FLAG_MUTABLE。更改应该很简单。 此外,如果您在应用中使用 AdMob 20.4.0 或更低版本,请确保添加以下工作管理器依赖项:
//Work Manager dependency
implementation 'androidx.work:work-runtime:2.7.1'
请注意,当前工作管理器依赖版本为 2.7.1。如果需要,可以更新版本到最新版本。
此崩溃已通过以下方式解决:实施 '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
版本
因为我的代码中有四个不同的 PendingIntents,所以我首先向所有这些添加 FLAG_IMMUTABLE。然而问题依然存在。 在花了很多时间分析我的 4 个意图之后,我突然意识到问题可能来自我的一个库。
在 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 个错误
如果您的应用面向 Android12(targetSdkVersion = 31)
,并且使用旧版本的WorkManager 直接或 通过任何 third-party 库 然后你需要 将它更新到最新的 来解决它。
dependencies {
def work_version = "2.7.1"
// (Java only)
implementation "androidx.work:work-runtime:$work_version"
// Kotlin + coroutines
implementation "androidx.work:work-runtime-ktx:$work_version"
}
对于 Java 开发者
PendingIntent pendingIntent = PendingIntent.getActivity(context, PENDING_INTENT_REQUEST_CODE,
notificationIntent,
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ?
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE : PendingIntent.FLAG_UPDATE_CURRENT);
我遇到过像 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)
)
如果您让您的应用在 android 12 中达到 运行,则有一个新的 PendingIntent 可变性标志。如果您不想让 PendingIntent 静音,请使用
Java
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 静音,请使用以下命令:
Java
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'
在我的项目中这条线有效
PendingIntent pendingIntent = PendingIntent.getActivity(this,0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
当您升级您的项目并针对 android 版本 12,Android 运行 应用程序在 Android 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'