创建 PendingIntent 时,针对 S+(版本 10000 及以上),需要指定 FLAG_IMMUTABLE 或 FLAG_MUTABLE 中的一个。

89
尝试将我的应用程序更新到Android S,但遇到了一些问题,如标题/错误所述。我收到以下错误消息:
目标S+(版本10000及以上)要求在创建PendingIntent时指定FLAG_IMMUTABLE或FLAG_MUTABLE之一。强烈建议使用FLAG_IMMUTABLE,仅在某些功能依赖于PendingIntent可变性的情况下使用FLAG_MUTABLE,例如,如果需要与内联回复或气泡一起使用。
我的代码中只有1个用于通知的PendingIntent,并添加了Flag。
PendingIntent.getActivity(
      mContext,
      0 /* Request code */,
      intentOptional.get(),
      PendingIntent.FLAG_IMMUTABLE
    )

阅读 Google 的文档,这应该是我在 Android S 安全更新中所需要的全部内容。我在这里找到了一个几个月前的帖子,询问类似的问题,有人建议将 WorkManager https://dev59.com/Y1EG5IYBdhLWcg3wX7z1#67181567 添加到项目中,即使您不使用它。所以我添加了。
def work_version = "2.7.0-alpha04" 
implementation "androidx.work:work-runtime-ktx:$work_version"

这并没有帮助我解决错误。有人知道这个Android S升级的常见问题吗?或者它是否也检查库?应用程序一直崩溃,不知道该怎么办。
我创建了一个没有任何库的应用程序,并使用相同的PendingIntent运行了一个基本的Hello World应用程序。我正在尝试编译的项目给出的完整错误是:
目标为S+(版本10000及以上)时,创建PendingIntent时需要指定FLAG_IMMUTABLE或FLAG_MUTABLE之一。强烈建议使用FLAG_IMMUTABLE,仅在某些功能依赖于PendingIntent可变性的情况下使用FLAG_MUTABLE,例如,如果需要与内联回复或气泡一起使用。
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 com.google.android.gms.internal.gtm.zzbv.zzfe(Unknown Source:52) at com.google.android.gms.internal.gtm.zzbv.cancel(Unknown Source:54) at com.google.android.gms.internal.gtm.zzbv.zzaw(Unknown Source:4) at com.google.android.gms.internal.gtm.zzan.zzag(Unknown Source:7) at com.google.android.gms.internal.gtm.zzap.(Unknown Source:67) at com.google.android.gms.internal.gtm.zzap.zzc(Unknown Source:82) at com.google.android.gms.analytics.GoogleAnalytics.getInstance(Unknown Source:15) at di.internal.module.ApplicationModule.providesGoogleAnalyticsLogger$app_developmentDebug(ApplicationModule.kt:339) at di.internal.module.ApplicationModule_ProvidesGoogleAnalyticsLogger$app_developmentDebugFactory.providesGoogleAnalyticsLogger$app_developmentDebug(ApplicationModule_ProvidesGoogleAnalyticsLogger$app_developmentDebugFactory.java:47) at di.internal.module.ApplicationModule_ProvidesGoogleAnalyticsLogger$app_developmentDebugFactory.get(ApplicationModule_ProvidesGoogleAnalyticsLogger$app_developmentDebugFactory.java:36) at di.internal.module.ApplicationModule_ProvidesGoogleAnalyticsLogger$app_developmentDebugFactory.get(ApplicationModule_ProvidesGoogleAnalyticsLogger$app_developmentDebugFactory.java:11) at dagger.internal.DoubleCheck.get(DoubleCheck.java:47) at di.internal.module.ApplicationModule_ProvidesMultiAnalyticsLogger$app_developmentDebugFactory.get(ApplicationModule_ProvidesMultiAnalyticsLogger$app_developmentDebugFactory.java:35) at di.internal.module.ApplicationModule_ProvidesMultiAnalyticsLogger$app_developmentDebugFactory.get(ApplicationModule_ProvidesMultiAnalyticsLogger$app_developmentDebugFactory.java:10) at dagger.internal.DoubleCheck.get(DoubleCheck.java:47) at di.internal.component.DaggerIProdApplicationComponent.injectChApplication(DaggerIProdApplicationComponent.java:941) 2021-07-02 11:18:17.611 22561-22561/com.chrobinson.navispherecarrier.dev E/AndroidRuntime: at di.internal.component.DaggerIProdApplicationComponent.inject(DaggerIProdApplicationComponent.java:876) at com.chrobinson.navispherecarrier.ChApplication.onCreate(ChApplication.kt:90) at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1211) at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6682)

com.google.android.gms.analytics.GoogleAnalytics.getInstance -- 你正在使用Google Analytics吗? - CommonsWare
我有一些遗留的 Google Analytics 事件,我还没有切换到 Firebase。 - Adam Gardner
根据堆栈跟踪,这就是你的崩溃来源。到明年,当你需要将targetSdkVersion升级到31时,你将需要升级此依赖项(以及其他可能的依赖项)。 - CommonsWare
我将com.google.android.gms:play-services-analytics设置为17.0.0,文档上也只有这一个版本。也许现在是时候完全移除Google Analytics并完全使用Firebase了。 - Adam Gardner
1
我在API 31(Android S正常)上遇到了同样的问题。我认为有一些库没有更新。我怀疑WorkManager是其中之一(也许检查Android版本的方法没有更新)。 - iClaude
18个回答

76

3
这应该是被接受的答案! - PieterAelse
2
这并不是一个错误,你看到的错误修复说明他们已经明确修复了崩溃问题,所以当前状态是正确的。你提到的版本只是2.7.0的alpha版本,实际发布版本在此alpha版本之后发布。所以你现在做的实际上是一个回归问题。相反,你可以使用“PendingIntent.FLAG_IMMUTABLE”或“PendingIntent.FLAG_UPDATE_CURRENT”。 - Aegletes
@Aegletes 但是在包含这个 alpha 版本之前,我已经尝试过 PendingIntent.FLAG_IMMUTABLE,但仍然遇到了异常。 - jomin v george
3
我花了一周时间检查我的代码,以确定是否有可能存在的错误和标志,但是没有发现任何问题。现在我添加了这行代码,一切都按预期运行了。为什么谷歌有时候会让我们的生活变得如此艰难呢?他们是不是根本没有检查他们发布的版本,或者为了满足期限而发布未经检查的代码?无论如何,非常感谢你。你让我省去了很多麻烦! - Nick
1
添加最新版本解决了我的问题。 ```def work_version = "2.7.0"// (仅适用于Java) implementation "androidx.work:work-runtime:$work_version"``` - Arshad Mehmood
显示剩余10条评论

43

根据文档,"创建 PendingIntent 时强烈推荐使用 FLAG_IMMUTABLE。只有在某些功能依赖于修改基础意图的情况下,例如需要与内联回复或气泡一起使用的任何 PendingIntent,才应该使用 FLAG_MUTABLE."

因此,请使用此 PendingIntent.FLAG_IMMUTABLE 或 PendingIntent.FLAG_UPDATE_CURRENT

而不仅仅是 PendingIntent.FLAG_UPDATE_CURRENT

例如: PendingIntent.getActivity(context, yourRequestID, yourIntent, PendingIntent.FLAG_IMMUTABLE 或 PendingIntent.FLAG_UPDATE_CURRENT)

因为 "即使设置了 FLAG_IMMUTABLE,FLAG_UPDATE_CURRENT 仍然有效"

如果错误仍然存在且您的 targetSdkVersion = 31,则错误必须是由于您的某个依赖项内部使用 WorkManager 或直接使用旧版 WorkManager 导致的。

要解决问题,只需添加此依赖项

implementation 'androidx.work:work-runtime-ktx:2.7.0'

1
值得一提的是文档中缺少的内容:当使用RemoveViews(例如用于检测小部件列表项上的单击事件)时,还需要FLAG_MUTABLE来使用setPendingIntentTemplate - Derek K
还要像这样更改服务类中的pndingIntent https://dev59.com/Y1EG5IYBdhLWcg3wX7z1#72363910 - Codeplayon
谢谢答案,运作得非常好。一个提示是,你可以使用最新版本的库,在我的情况下,我使用了implementation 'androidx.work:work-runtime-ktx:2.7.1'。 - Desilio Neto

25
将您的待定意图添加如下所示:

将您的待定意图添加如下:

 PendingIntent.getActivity(getApplicationContext(), 0, intent,PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT)

17

在阅读了这里的答案后,我发现在Android的网站上有以下内容:

注意:针对 Android 12(S)的应用程序需要 WorkManager Version 2.7.0。

https://developer.android.com/jetpack/androidx/releases/work

因此,添加此依赖项将使其正常工作。

 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"

救命稻草,即使是 alpha 版本也不能工作。你必须拥有完整版本。 - emanuel sanga
应该选择最好解释如何修复的答案作为正确答案,谢谢。 - FabioR

5

有两个步骤

1- 添加显示在错误信息中的 androidx.work

dependencies {
    implementation 'androidx.work:work-runtime-ktx:2.7.1'}

2- 通过修改或添加 FLAG_IMMUTABLE 来修复 PendingIntent

PendingIntent pendingIntent =
                PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT);
    

2
嗨!我需要在哪里添加这个PendingIntent?非常感谢。 - Nicolas Papp
@NicolasPapp,在这个类NewAppWidget中,继承了AppWidgetProvider,在updateAppWidget方法下。 - Mori
你好 为什么不呢PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT);目的是为了区别。 - undefined
PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT 为我工作。谢谢。 - undefined

2
如果您正在使用Google AdMob SDK(版本20.4.0),他们建议在AdMob官方发布说明中添加此约束条件。
链接:https://developers.google.com/admob/android/rel-notes?hl=en
dependencies {
  implementation 'com.google.android.gms:play-services-ads:20.4.0'

  // For apps targeting Android 12, add WorkManager dependency.
  constraints {
    implementation('androidx.work:work-runtime:2.7.0') {
      because '''androidx.work:work-runtime:2.1.0 pulled from
      play-services-ads has a bug using PendingIntent without
      FLAG_IMMUTABLE or FLAG_MUTABLE and will fail in Apps
      targeting S+.'''
    }
  }
}

2

我将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版本解决了上述错误


2
在Android Studio中,按照以下步骤操作:
1. 打开 "文件" 菜单,选择 "项目结构"。 2. 进入 "依赖项" -> "应用程序"。 3. 检查是否有任何带有建议的下划线依赖项,如果有,请让工作室正确实现它们。 4. 使用 "implementation 'androidx.work:work-runtime-ktx:2.7.1'" 解决问题。
备注:您无法在 gradle 中看到此类建议。

2

我在Android 12上遇到了一个类似的问题。

PendingIntent.java – 第375行 android.app.PendingIntent.checkFlags enter image description here

通过更新Onesignal依赖项解决了这个问题。

    implementation 'com.onesignal:OneSignal:4.6.3'

1

你需要这个。

dependencies {
    implementation 'androidx.work:work-runtime:2.7.1'
    implementation 'com.google.firebase:firebase-messaging:21.0.1'
    implementation('com.google.firebase:firebase-iid:21.1.0')
    implementation platform('com.google.firebase:firebase-bom:31.1.0')
}

谢谢兄弟,这在Ionic API Level 33中对我很有效。 - Sahilbalgotra100

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接