Android Studio error: "Manifest merger failed: Apps targeting Android 12"

Android Studio error: "Manifest merger failed: Apps targeting Android 12"

我已经将我的模拟器版本和Android SDK版本更新为Android S(Android 12). After the update, I cannot run the project. I cannot run a Hello, World!项目(空项目),但我可以构建Gradle 以及,但我不能 运行 项目。我总是得到错误:

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.

我该如何解决?

这是截图:

使用Android 12 SDK时如何解决这个问题?

is about the issue after applying the solution to this, and is different than this question. Also, this question is older than .

您需要指定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>

the document所述:

If your app targets Android 12 and contains activities, services, or broadcast receivers that use intent filters, you must explicitly declare the android: exported attribute for these app components.

Warning: If an activity, service, or broadcast receiver uses intent filters and doesn't have an explicitly-declared value for android:exported, your app can't be installed on a device that runs Android 12.

还有 check 何时使用 true/false 作为 'android:exported' 值。

您的问题可能已被标记为重复,因为 post:,尽管您的问题是在 post 一周前编辑的。我现在看不到旗帜了。

为了澄清 ,请注意 android:exported 应该为您的主 activity 设置为真,否则它不会尽管来自 Android Studio 的令人鼓舞的 'Launch succeeded' 消息仍启动,因为没有其他应用程序甚至 Android 系统本身可以启动它。

<activity
    android:name=".MainActivity"
    android:exported="true"

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

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

完成!您可以在 Android 12.

上 运行 您的应用
<manifest ... >

    <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>
</manifest>

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

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

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

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

来自Android Documentation

我还必须将 android:exported="true" 添加到我在清单中声明的​​所有 receiver。所以我有这样的事情:

<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>

我认为您不应该将 android:exported="true" 添加到所有内容。你应该只在那些广播接收器需要对 Android OS 可见时添加它。该代码中的 Intent 过滤器意味着我希望 Android OS 唤醒我的 Android 应用程序并执行操作。

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

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

问题是项目很大,有多个 AndroidManifest.xml 个文件,android:exported 很多地方都不见了。

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

这里是 link.

This will help for 2021 users.

在您的两个 build.gradle 文件之一中,您应该能够找到 targetSDK 31 行。将其更改为 30,然后执行 gradle 同步(一个小条将出现在主屏幕上方代码 window 您可以在其中单击“立即同步”),您应该可以开始了。

在您的启动器 activity 中,声明“android:已导出”:

<activity android:name=".MainActivity"
          android:exported = "false">

    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>

</activity>

如果为真“android: exported= true”,这意味着 activity 可以被任何应用程序访问,并且可以通过其确切的 class 名称启动。

如果为 false “android: exported = false” 表示 activity 只能由具有相同用户 ID 的同一应用程序的组件或特权系统组件启动。

有关详细信息,请查看 here

如果您在清单中没有找到没有标签“android: exported = false”的 activity 的地方,那么它很可能在您的依赖项中。 .为了准确定位,首先将“compileSdkVersion”降级为30,将“targetSdkVersion”降级为30,以便构建。

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

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

在那之后,在主要 manifest.xml window 中有一个带有“合并清单”的选项卡。在那里你可以检查 activity 到底有没有“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"

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

<service
    android:name=".autofillservice.MyAutofillService"
    android:exported="true"
    android:permission="android.permission.BIND_AUTOFILL">

<service
    android:name="com.demo.myApp.my_access.MyAccessService"
    android:enabled="true"
    android:exported="true"
    android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">

因为我的问题出在第三方依赖上,而且不会很快更新,所以我只是添加了一个带有标志 android:exported="true" 的 声明并导出="false" 在需要覆盖初始声明的地方,因为我只需要在 Debug 中使用此依赖项,所以我在 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>

您不妨只使用 tools:node="merge" 属性并将 android:exported=true|false 声明为

即使我在所有活动、接收器等中添加 android:exported="true" 时,我也会收到此错误。对我有用的是将 compileSdkVersiontargetSdkVersion 更改为 30。

androidTestImplementation 'androidx.test.ext:junit:1.1.1'的版本更新到最新版本,如:-androidTestImplementation 'androidx.test.ext:junit:1.1.3'来自build.gradle 应用级别.

针对 Android 12

的应用

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

然后在清单中指定 android:exorted="" 属性 true 或 false 取决于 Activity

对于 Laucher Activity 例如 Splash 或 MainActivity 使用 android:exported="true" 其余活动使用 android:exported="false"

例如:

    //it's **true** for laucher Activity
    <activity android:name=".SplashActivity"
              android:exported="true" />

     //it's **false** for rest Activities
     <activity android:name=".MainActivity"
              android:exported="false" />

//启动器要求的注释activity

<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>

接收方要求

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

服务需要

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