清单合并失败:针对 Android 12 的应用程序 - Android Studio 错误

DSF*_*Inc 29 java android runtime-error android-emulator android-studio

首先,这不是重复的。

我已将模拟器版本和 android SDK 版本更新为 Android S (Android 12) 但更新后。我无法运行该项目。我无法运行 hello world 项目(空项目)。但是我可以构建成绩,但不能运行该项目。我总是收到错误:

***Manifest merger failed: 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.***
Run Code Online (Sandbox Code Playgroud)

请任何人都可以帮助我吗?

这是一个截图...

这是一个截图。

小智 58

如果您在清单中没有找到没有标签“android:exported = false”的活动的地方,那么它很可能在您的依赖项中......为了查明具体位置,首先降级“compileSdkVersion”为 30,“targetSdkVersion”为 30,这样就可以构建了。

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

    defaultConfig {
        ...
        minSdkVersion 23
        targetSdkVersion("S")
        ...
}
Run Code Online (Sandbox Code Playgroud)

之后,在主manifest.xml窗口中,有一个带有“合并清单”的选项卡。在那里您可以检查哪些活动到底没有“android:exported = false”属性。

就我而言,这是因为第三方工具:

文件build.gradle(:应用程序):

debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.7'
//and
debugImplementation "com.github.markzhai:blockcanary-android:1.5.0"
releaseImplementation "com.github.markzhai:blockcanary-no-op:1.5.0"
Run Code Online (Sandbox Code Playgroud)

另外,对于服务我必须添加属性:

<service
    android:name=".autofillservice.MyAutofillService"
    android:exported="true"
    android:permission="android.permission.BIND_AUTOFILL">
Run Code Online (Sandbox Code Playgroud)

<service
    android:name="com.demo.myApp.my_access.MyAccessService"
    android:enabled="true"
    android:exported="true"
    android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
Run Code Online (Sandbox Code Playgroud)

由于我的问题出在第三方依赖项上,并且不会很快更新,因此我只是在需要覆盖初始声明的地方添加了带有标志 android:exported="true" 和导出的="false" 的 <activity> 声明,另外,因为我只在调试中需要此依赖项,所以我在 src/debug 中添加了一个新的 AndroidManifest.xml 文件:

对于leak_canary:

<?xml version="1.0" encoding="UTF-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android">

    <application>
        <activity
            android:name="leakcanary.internal.activity.LeakActivity"
            android:exported="true"
            android:icon="@mipmap/leak_canary_icon"
            android:label="@string/leak_canary_display_activity_label"
            android:taskAffinity="com.squareup.leakcanary.${applicationId}"
            android:theme="@style/leak_canary_LeakCanary.Base">

            <intent-filter android:label="@string/leak_canary_import_hprof_file">

                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data android:scheme="file" />
                <data android:scheme="content" />
                <data android:mimeType="*/*" />
                <data android:host="*" />

                <data android:pathPattern=".*\\.hprof" />
                <data android:pathPattern=".*\\..*\\.hprof" />
                <data android:pathPattern=".*\\..*\\..*\\.hprof" />
                <data android:pathPattern=".*\\..*\\..*\\..*\\.hprof" />
                <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.hprof" />
                <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\.hprof" />
                <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\.hprof" />
            </intent-filter>
        </activity>

        <activity
            android:name="leakcanary.internal.RequestStoragePermissionActivity"
            android:excludeFromRecents="true"
            android:exported="false"
            android:icon="@mipmap/leak_canary_icon"
            android:label="@string/leak_canary_storage_permission_activity_label"
            android:taskAffinity="com.squareup.leakcanary.${applicationId}"
            android:theme="@style/leak_canary_Theme.Transparent" />

        <receiver
            android:name="leakcanary.internal.NotificationReceiver"
            android:exported="false" />

    </application>
</manifest>
Run Code Online (Sandbox Code Playgroud)

您也可以使用 tools:node="merge" 属性并按照LeoFarage 的建议声明 android:exported=true|false 。

  • 您不需要完全覆盖活动条目。您可以使用`tools:node="merge"`属性并声明`android:exported=true|false`。这应该将该属性添加到最终合并的 AndroidManifest 中的目标 Activity。检查此链接,了解如何处理项目中的清单:https://developer.android.com/studio/build/manage-manifests (6认同)
  • 感谢您提供这个非常有帮助的答案。不幸的是,在我的(相当大的)项目中,“MergedManifest”视图不起作用并显示空屏幕。但是,在成功构建后,您可以在输出目录中轻松找到合并的清单,即“app/build/intermediates/merged_manifests/debug/AndroidManifest.xml”之类的内容。只需在此文件中搜索“&lt;intent-filter&gt;”标签即可。在我的例子中,外部库声明了一个带有意图过滤器的活动,但错过了“导出”标志。将此库更新到最新版本解决了我的问题。 (3认同)

Mit*_*ani 29

您需要指定android:exported="false"android:exported="true"

显现:

<activity
          android:name=".MainActivity"
          android:exported="true"
          android:theme="@style/Theme.MyApplication.NoActionBar">
          <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
          </intent-filter>
    </activity>
Run Code Online (Sandbox Code Playgroud)

文件中所述

如果您的应用面向 Android 12 并包含使用 Intent 过滤器的活动、服务或广播接收器,则您必须明确声明这些应用组件的 android: 导出属性。

警告:如果活动、服务或广播接收器使用意图过滤器并且没有明确声明的 android:exported 值,则您的应用无法安装在运行 Android 12 的设备上。

还要检查何时对 'android:exported' 值使用 true/false

  • @MarcCalandro我跟进了所有步骤,还包括导出= true,但发生了相同的错误。有什么建议..? (58认同)
  • 是的,我不明白为什么这被接受为解决方案。我已将 android:exported 放在带有/不带有意图过滤器的每个活动上。还是不行。很可能是由某种依赖性造成的。 (17认同)
  • 您只需指定 android:exported。但根据您的用例,您可以将其设置为 true 或 false (4认同)
  • 这为我解决了这个问题:/sf/answers/4736768151/ (3认同)
  • 感谢@Alix 向我指出此 stackoverflow.com/a/67668116/1859486 。如果仍然失败,那么您还需要将 `android:exported` 添加到您的接收器 /sf/answers/4802353461/ (2认同)

Dat*_*Tat 29

在我的项目中定位 Android 12 后,我遇到了同样的问题。

问题是项目相当大,有多个AndroidManifest.xml文件,而且android:exported很多地方都丢失了。

我最终创建了一个Gradleandroid:exported任务来自动为我填充缺失的属性。

链接在这里。


Noa*_*oah 22

android:exported属性设置组件(活动、服务、广播接收器等)是否可以由其他应用程序的组件启动:

  • 如果为 true,则任何应用程序都可以访问该 Activity 并通过其确切的类名称启动它。
  • 如果为 false,则只有同一应用程序的组件、具有相同用户 ID 的应用程序或特权系统组件才能启动该活动。

该属性的默认值背后的逻辑随着时间的推移而变化,并且根据组件类型和 Android 版本而有所不同。例如,在 API 级别 16 (Android 4.1.1) 或更低版本上,元素的值默认设置为 true。不显式设置此属性会带来某些设备之间具有不同默认值的风险。

摘自官方文档

自Android 12设备以来,情况发生了变化,因此您需要执行以下操作:

添加到清单中声明的android:exported="true"​​所有接收者。

<receiver android:name=".alarms.AlarmReScheduler"
          android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
        <action android:name="android.intent.action.BOOT_COMPLETED" />
        <action android:name="android.intent.action.QUICKBOOT_POWERON" />
        <action android:name="android.intent.action.PACKAGE_REPLACED" />

        <!-- For HTC devices -->
        <action android:name="com.htc.intent.action.QUICKBOOT_POWERON" />
    </intent-filter>
</receiver>
Run Code Online (Sandbox Code Playgroud)

也适用于活动(由 Android 操作系统又称为启动器活动启动的活动)

      <activity
         android:name=".main.SplashScreen"
         android:exported="true"
         android:theme="@style/FullscreenTheme">
         <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
         </intent-filter>
      </activity>
Run Code Online (Sandbox Code Playgroud)

注意:对于使用意图过滤器的服务和广播接收器,您必须显式声明该android: exported属性。

不要只是添加android:exported="true"所有内容。在广播接收器需要对 Android 操作系统可见的情况下,您可能需要指定android:exported. 该代码中的 Intent 过滤器意味着我希望 Android 操作系统唤醒我的 Android 应用程序并执行操作。

android.intent.action.BOOT_COMPLETED这是一个非常好的例子,因为 Android 操作系统向设备中安装的每个应用程序发送广播。因此从技术上讲,这意味着任何具有带有操作的意图过滤器的广播接收器都应该始终声明android:exported="true".


Reh*_*han 17

对于面向 Android 12 的应用

将应用程序的 targetSdkVersion 更改为S(32 或 31)以启用新行为。

然后根据 Activity 将Manifest 中的android:exported=""属性指定为 true 或 false。

对于启动器活动(例如splash或MainActivity),请使用android:exported =“true”,对于其余活动,请使用android:exported =“false”

例如:

<!-- It's **true** for the launcher Activity -->
<activity android:name=".SplashActivity"
          android:exported="true" />

<!-- It's **false** for the rest of the Activities -->
<activity android:name=".MainActivity"
          android:exported="false" />
Run Code Online (Sandbox Code Playgroud)


Tom*_*one 16

在清单中,在默认启动活动属性中添加 android:exported="true" 或 android:exported="false "。

完毕!您可以在 Android 12 上运行您的应用程序。

启动器活动所需

<activity
    android:name=".MainActivity"
    android:exported="true"
    android:theme="@style/Theme.MyApplication.NoActionBar">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>
Run Code Online (Sandbox Code Playgroud)

接收者要求

<receiver android:name=".Musicreceiver"
          android:exported="true">

</receiver>
Run Code Online (Sandbox Code Playgroud)

服务所需


    <service
        android:name=".service.LoggerService"
        android:exported="true"
        android:enabled="true" />

Run Code Online (Sandbox Code Playgroud)


And*_*der 13

由于这篇文章,您的问题可能会被标记为重复:Manifest merge failed Targeting Android 12,尽管您的问题是在一周前发布的。我现在看不到旗帜了。

为了澄清另一个答案,请注意android:exported应该为您的主要活动设置为 true,否则尽管 Android Studio 发出令人鼓舞的“启动成功”消息,但它不会启动,因为没有其他应用程序,甚至 Android 系统本身可以启动它。

<activity
    android:name=".MainActivity"
    android:exported="true"
Run Code Online (Sandbox Code Playgroud)

对于其他隐藏在合并清单中的意图的活动,这通常会设置为 false。


Shi*_*din 10

在您的清单中,在您的默认启动活动属性中添加android:exported="true"或 android:exported="false "。

完毕!。您可以在Android 12上运行您的应用程序。

<表明...

<activity
        android:name=".ui.dashboard.DashboardActivity"
        android:screenOrientation="portrait"
        android:exported="true"
        android:theme="@style/AppTheme.Launcher">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
Run Code Online (Sandbox Code Playgroud)

根据您的要求设置android:exported值。

广播接收器是否可以从其应用程序之外的非系统源接收消息 - 如果可以,则为“true”,否则为“false”。如果为“false”,则广播接收器只能接收由系统、同一应用程序的组件或具有相同用户 ID 的应用程序发送的消息。

如果未指定,默认值取决于广播接收器是否包含意图过滤器。如果接收器包含至少一个意图过滤器,则默认值为“true”。否则,默认值为“false”。

此属性不是限制广播接收器的外部暴露的唯一方法。您还可以使用权限来限制可以发送消息的外部实体(请参阅权限属性)。

来自Android 文档

  • 对我不起作用。看起来我们中的一些人通过第三方库遇到了这个问题,在这种情况下这无法解决它。 (16认同)

归档时间:

查看次数:

22992 次

最近记录:

4 年,1 月 前