清单合并失败,目标为Android 12。

78

在我的build.gradle文件中将sdk目标更改为Android 12后,使用Android Studio 4.2.1时,我遇到了“清单合并失败,查看日志以获取多个错误”的错误。

在“合并的清单”选项卡中显示的错误如下:

Merging Errors: 
Error: Apps targeting Android 12 and higher are required to specify an explicit value for `android:exported` when the corresponding component has an intent filter defined. See https://developer.android.com/guide/topics/manifest/activity-element#exported for details. My_App.app main manifest (this file) 
Error: Apps targeting Android 12 and higher are required to specify an explicit value for `android:exported` when the corresponding component has an intent filter defined. See https://developer.android.com/guide/topics/manifest/activity-element#exported for details. My_App.app main manifest (this file) 
Error: Apps targeting Android 12 and higher are required to specify an explicit value for `android:exported` when the corresponding component has an intent filter defined. See https://developer.android.com/guide/topics/manifest/activity-element#exported for details. My_App.app main manifest (this file) 

然而android:exported标签已经应用在我的AndroidManifest.xml文件中。我只有一个活动,没有服务或广播接收器。请参见以下内容:


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.mydomain.myapp">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.VIBRATE" />

    <application
        android:name="com.mydomain.myapp.MyApplication"
        android:allowBackup="false"
        tools:replace="allowBackup"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name="com.mydomain.myapp.ui.MainActivity"
            android:exported="true">
            <intent-filter >
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <meta-data
            android:name="preloaded_fonts"
            android:resource="@array/preloaded_fonts" />
    </application>

</manifest>

我的 build.gradle(:app) 文件:

android {
    compileSdkVersion("android-S")
    buildToolsVersion "30.0.3"

    defaultConfig {
        ...
        minSdkVersion 23
        targetSdkVersion("S")
        ...
}

你有什么想法可以解决这个问题吗?


2
你确定在合并清单选项卡中显示的清单不包含其他组件吗?库可以提供活动、服务和接收器。 - CommonsWare
4
问题似乎确实是由于第三方库缺少android:exported标记引起的。合并清单选项卡显示为空("Nothing to show")是因为合并失败,所以我必须使用低于Android 12的目标重新构建来进行调查。谢谢! - SVP
7
这很有趣,感觉像是Studio的一个bug或者限制。即使它不能提供普通Merged Manifest选项卡的所有功能,至少也应该显示合并后清单文件包含了什么,以应对这种情况。 - CommonsWare
1
@CommonsWare同意。如果右侧面板中的错误可以指出导致错误的组件,那就更好了。为了增加混淆,在右侧面板的顶部,它写着:“其他清单文件(包含在合并中,但没有贡献任何元素)”,我理解为“其他清单文件不是错误的来源”。 - SVP
1
@CommonsWare 对于项目所需但未更新以针对Android 12进行测试的第三方库,通过指定android:exported标志如何处理?我正在处理一个具有许多依赖项的大型框架,并希望对Android 12进行测试。我知道其中一些库不会很快更新清单。我们应该查看失败的清单合并并显式覆盖所有尚未设置其“导出”标志的意图吗? - dell116
显示剩余6条评论
8个回答

171

问题是由于在androidx.test:core库版本1.3.0中缺少android:exported属性的3个活动引起的。升级到版本1.4.0-beta01解决了这个问题。

如果您在针对Android 12进行目标设置后出现错误,最简单的调试方法是:

  • 降级到先前的sdk版本
  • 重新构建项目
  • 成功构建后,打开项目的AndroidManifest.xml文件。
  • 在窗口底部,单击Merged Manifest选项卡
  • 查找任何包含<intent-filter>标签并且缺少android:exported属性的<activity>

如果您想确保这些活动是问题所在,请直接将它们添加到您的项目的AndroidManifest.xml文件中,并添加缺少的android:exported属性,然后尝试重新构建项目。

因此,如果<activity android:name="com.domain.ProblemActivity">缺少android:exported属性,请像下面这样将其添加到您的AndroidManifest.xml文件中:

<activity 
 android:name="com.domain.ProblemActivity"
 android:exported="true" >

重新构建以针对 Android 12,如果它可以工作,那么你就找到了 Bug!

感谢 @MikePenz 指出了正确的方向。


2
这些步骤确实有所帮助。我忘记了使用导航组件中的<nav-graph>也会生成<intent-filter>标签。你还需要将exported属性添加到那些活动中。 - Arieck
5
我的项目中出现问题了。我没有使用带有exported属性的intent-filter,但是仍然遇到了编译错误!我该如何找到没有exported属性的activity所在的位置? - Sergio
18
通过运行 gradlew processDebugAndroidTestManifest --debug 命令并向上滚动到显示“针对 Android 12 及更高版本的应用程序...”文本的位置,我能够找出导致我的项目问题的原因。在我的情况下,它上面的 INFO 行显示了需要更新为 3.4.0 版本的 espresso 合并。另一个需要更新的是 WorkManager。 - Blake
4
如果将其添加到 <activity> 后仍然失败,您还需要将 android:exported 添加到您的 receiver 中。https://dev59.com/p1EG5IYBdhLWcg3wW7I5#68605049 - Alexa289
2
我在进行(导航/Compose测试)codelabs期间运行测试时遇到了这个问题。正如@Blake所说,我运行了./gradlew processDebugAndroidTestManifest --debug。对我来说,它是espresso-contribespresso-core。按下**ctrl+alt+shift+s*,选择Dependencies,然后选择可用的最高版本(此时为3.5.0-alpha03),在跟进ApplyOk*后解决了问题。 - Rik
显示剩余7条评论

9

如果您的应用程序针对Android 12或更高版本,并且包含使用意图过滤器的活动、服务或广播接收器,则必须显式声明这些应用程序组件的 android:exported 属性。为了解决此问题,我们需要按照以下步骤操作:

  1. 我们需要在主文件夹中找到 AndroidManifest.xml。

android>app>src>main>AndroidManifest.xml

enter image description here

  1. 我们必须添加android:exported=""并在这些引号中设置一个布尔值。现在你可能会问,何时需要将android:exported =“true”android:exported =“false”添加到使用意图过滤器的活动、服务或广播接收器中。 如果应用程序组件包括 LAUNCHER 类别,则将 android:exported 设置为 true。在大多数其他情况下,将 android:exported 设置为 false。

  2. 以下是 AndroidManifest.xml 中的示例

<service android:name="com.example.app.backgroundService"
         android:exported="false">
    <intent-filter>
        <action android:name="com.example.app.START_BACKGROUND" />
    </intent-filter>
</service>

您可以通过以下链接了解更多有关此主题的信息:

Android 12 的更安全的组件导出


6
如果您将Android Studio升级到Bumblebee 2021.1.1,需要进行以下更改: 步骤1:您的targetSdkVersion必须是30或更高版本。 步骤2:更新您的appcompat库至implementation 'androidx.appcompat:appcompat:1.4.1'。 步骤3:在AndroidManifest文件中为您的活动启动器添加android:exported = true

2
我已经正确设置了我的Activity,其中包括“exported=true”,但仍然遇到了以下问题:
Installation failed due to [...] androidx.test.core.app.InstrumentationActivityInvoker$BootstrapActivity: Targeting S+ (version 31 and above) requires that an explicit value for android:exported be defined when intent filters are present

所以我看到了这篇 Github 帖子,它可能解释了为什么会发生这种情况,并应用了 yogurtearl 建议的解决方法,对我起了作用。

https://github.com/android/android-test/issues/832

基本上是这样的:
作为一种解决方法,将此代码放入 app/src/debug/AndroidManifest.xml 中,它将强制在同一测试进程中启动这些代码。
    <activity
        android:name="androidx.test.core.app.InstrumentationActivityInvoker$BootstrapActivity"
        android:exported="true"
        android:theme="@android:style/Theme" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
        </intent-filter>
    </activity>
    <activity
        android:name="androidx.test.core.app.InstrumentationActivityInvoker$EmptyActivity"
        android:exported="true"
        android:theme="@android:style/Theme" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
        </intent-filter>
    </activity>
    <activity
        android:name="androidx.test.core.app.InstrumentationActivityInvoker$EmptyFloatingActivity"
        android:exported="true"
        android:theme="@android:style/Theme.Dialog" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
        </intent-filter>
    </activity>

并将它们的“exported=true”添加到其中。

2

我曾遇到过这个问题,解决方法是:

  • 如果你的AndroidManifest文件中有任何活动、服务、接收器或提供者没有设置exported属性,则在该活动、服务、接收器或提供者中添加以下属性

android:exported="false or true"


0

别忘了也把它放到服务标签中

    <service
        android:name=".service.MyIME"
        android:exported="true"
        android:permission="android.permission.BIND_INPUT_METHOD">
        <meta-data
            android:name="android.view.im"
            android:resource="@xml/method" />

        <intent-filter>
            <action android:name="android.view.InputMethod" />
        </intent-filter>
    </service>

0

如果您正在使用DexGuard,请更新到最新版本9.2.11(截至2022年1月19日)。

发布说明中的引用:

添加默认配置以保留exported属性,这是针对Android 12的应用程序所需的。


0
如下链接所示-https://developer.android.com/about/versions/12/behavior-changes-12#exported,使用意图过滤器的 Android 组件必须明确定义组件导出,否则您的应用程序将无法安装在运行 Android 12 或更高版本的设备上。应用程序组件包括活动、服务、广播接收器和内容提供者。
如果应用程序组件包括 LAUNCHER 类别,则将 android:exported 设置为 true。在大多数其他情况下,将 android:exported 设置为 false。
即使设置了 android:exported 标记,如果仍然遇到清单合并失败问题,则检查您在应用程序中使用的所有库。在 Android Studio 的项目视图中打开外部库并尝试检查您已包含在项目中的所有库的清单文件。其中任何一个库都可能没有根据 Android 12 进行更新。因此,如果找到任何缺少导出标记的库的清单文件,请尝试编辑该文件并在其中添加此标记。希望这有助于消除清单合并错误。

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