简体   繁体   English

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

[英]Android Studio error: "Manifest merger failed: Apps targeting Android 12"

I have updated my emulator version and Android SDK version to Android S ( Android 12 ).我已将我的仿真器版本和 Android SDK 版本更新为 Android S ( ZE84E30B9390CDB64DB612C98846AB )。 After the update, I cannot run the project.更新后,我无法运行该项目。 I cannot run a Hello, World!我无法运行Hello, World! project (empty project), but I can build Gradle as well as, but I can not run the project.项目(空项目),但我可以构建 Gradle 以及,但我无法运行该项目。 I always got the error:我总是得到错误:

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.清单合并失败:针对 Android 12 及更高版本的应用程序需要为android: exported See https://developer.android.com/guide/topics/manifest/activity-element#exported for details.有关详细信息,请参阅https://developer.android.com/guide/topics/manifest/activity-element#exported

How can I fix it?我该如何解决?

Here is a screenshot:这是一个屏幕截图:

这是一个屏幕截图。

How can I solve this issue when using Android 12 SDK?使用 Android 12 SDK 时如何解决此问题?

This question is about the issue after applying the solution to this, and is different than this question. 这个问题是关于应用解决方案后的问题,并且与这个问题不同。 Also, this question is older than this .此外,这个问题比this更老。

You need to specify android:exported="false" or android:exported="true"您需要指定android:exported="false"android:exported="true"

Manifest:显现:

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

as mentioned in 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.如果您的应用程序以 Android 12 为目标并包含使用意图过滤器的活动、服务或广播接收器,则您必须显式声明 android:这些应用程序组件的导出属性。

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

Also check when to use true/false for the 'android:exported' value.还要检查何时对“android:exported”值使用真/假。

In your manifest, add android:exported="true" or android:exported="false " in your default launching activity attribute.在您的清单中,在默认启动活动属性中添加android:exported="true"或 android:exported="false"。

Done!完毕! You are all right to run your apps on Android 12 .您可以在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>

Set the android:exported value according to your requirement.根据您的要求设置android:exported值。

Whether the broadcast receiver can receive messages from non-system sources outside its application — "true" if it can, and "false" if not.广播接收器是否可以从其应用程序之外的非系统源接收消息 - 如果可以,则为“true”,否则为“false”。 If "false", the only messages the broadcast receiver can receive are those sent by the system, components of the same application, or applications with the same user ID.如果为“false”,则广播接收器只能接收由系统、同一应用程序的组件或具有相同用户 ID 的应用程序发送的消息。

If unspecified, the default value depends on whether the broadcast receiver contains intent filters.如果未指定,则默认值取决于广播接收器是否包含意图过滤器。 If the receiver contains at least one intent filter, then the default value is "true".如果接收器包含至少一个意图过滤器,则默认值为“true”。 Otherwise, the default value is "false".否则,默认值为“false”。

This attribute is not the only way to limit a broadcast receiver's external exposure.此属性不是限制广播接收器外部暴露的唯一方法。 You can also use permission to limit the external entities that can send messages (see the permission attribute).您还可以使用权限来限制可以发送消息的外部实体(请参阅权限属性)。

From Android Documentation来自Android 文档

If you didn't find in your manifest the place where there is an activity without the tag "android: exported = false" then it's likely that it is in your dependencies... in order to pinpoint where exactly, first downgrade "compileSdkVersion" to 30 and "targetSdkVersion" to 30 so it builds.如果您在清单中没有找到没有标签“android:exported = false”的活动的地方,那么它很可能在您的依赖项中......为了准确定位,首先降级“compileSdkVersion”到 30 和“targetSdkVersion”到 30 所以它构建。

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

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

After that, in the main manifest.xml window there is a tab with "merged manifest".之后,在主清单中。xml window 有一个带有“合并清单”的选项卡。 There you can inspect what activity exactly didn't have the "android: exported = false" attribute.在那里您可以检查哪些活动完全没有“android:exported = false”属性。

In my case it was because of third-party tools:就我而言,这是因为第三方工具:

build.gradle (: app): 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"

Also, for services I had to add the attribute:此外,对于服务,我必须添加属性:

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

and

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

As my problem was in a third-party dependency and it's not going to be updated soon, I just added a <activity> declaration with the flag android:exported="true" and exported="false" where needed to override the initial declaration, also as I need this dependency in Debug only I added a new AndroidManifest.xml file in src/debug:由于我的问题在于第三方依赖项并且不会很快更新,我只是添加了一个带有标志 android:exported="true" 和 exports="false" 的 <activity> 声明,以覆盖初始声明,因为我只需要在 Debug 中使用这个依赖项,所以我在 src/debug 中添加了一个新的 AndroidManifest.xml 文件:

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

You might as well just use the tools:node="merge" attribute and declare the android:exported=true|false as LeoFarage kindly suggested .您不妨使用 tools:node="merge" 属性并声明 android:exported=true|false 正如LeoFarage 所建议的那样。

I ran into the same issue after targeting Android 12 in my project.在我的项目中以 Android 12 为目标后,我遇到了同样的问题。

The problem was the project was quite big, with multiple AndroidManifest.xml files, and android:exported missing in many places.问题是项目很大,有多个AndroidManifest.xml文件,并且android:exported在很多地方都丢失了。

I ended up creating a Gradle task to fill the missing android:exported attributes automatically for me.我最终创建了一个Gradle任务来自动为我填充缺失的android:exported属性。

Here is the link .这是链接

Your question may have flagged for duplication because of this post: Manifest merger failed targeting Android 12 , although yours was posted a week earlier.由于这篇文章,您的问题可能已被标记为重复: Manifest merge failed 针对 Android 12 ,尽管您的问题是在一周前发布的。 I don't see the flag now.我现在看不到国旗。

To clarify another answer , note that android:exported should be set true for your main activity, or it won't launch despite an encouraging 'Launch succeeded' message from Android Studio as no other app, or even the Android system itself, can launch it.要澄清另一个答案,请注意android:exported应该为您的主要活动设置为 true,否则尽管 Android Studio 发出令人鼓舞的“启动成功”消息,但它不会启动,因为没有其他应用程序,甚至 ZE84E30B9390CDB6DAB874 系统本身都无法启动,它。

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

For other activities with intents buried in your merged manifests, this would normally be set to false.对于其他意图隐藏在合并清单中的活动,这通常设置为 false。

I had to also add android:exported="true" to all my receiver s declared in the manifest.我还必须将android:exported="true"添加到清单中声明的所有receiver中。 So I had something like this:所以我有这样的事情:

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

I don't think you should add android:exported="true" to just everything.我认为您不应该将android:exported="true"添加到所有内容中。 You should only add that when those Broadcast receivers need to be visible to Android OS.您应该仅在需要对 Android 操作系统可见这些广播接收器时添加它。 The Intent filters in that code mean that I wanted Android OS to wake up my Android app and perform an operation.该代码中的意图过滤器意味着我希望 Android 操作系统唤醒我的 Android 应用程序并执行操作。

android.intent.action.BOOT_COMPLETED is a very good example because Android OS sends broadcasts to every application installed in the device. android.intent.action.BOOT_COMPLETED是一个很好的例子,因为 Android 操作系统会向设备中安装的每个应用程序发送广播。 So technically, it would mean that any Broadcast receiver that has an intent filter with actions should always declare android:exported="true" .所以从技术上讲,这意味着任何具有带有动作的意图过滤器的广播接收器都应该始终声明android:exported="true"

For apps targeting Android 12对于针对 Android 12 的应用程序

Change your app's targetSdkVersion to S(32 Or 31) to enable the new behavior.将应用的targetSdkVersion 更改为 S(32 或 31)以启用新行为。

Then Specify android:exorted="" attribute in Manifest either true or false depends on Activity然后在 Manifest 中指定 android:exorted="" 属性是 true 还是 false 取决于 Activity

For Laucher Activity Such As Splash or MainActivity Use android:exported="true" and for the rest Activities use android:exported="false"对于诸如 Splash 或 MainActivity 之类的 Laucher 活动,使用 android:exported="true",对于 rest 活动,使用 android:exported="false"

Eg:例如:

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

//Note required by launcher 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>

required by recevier接收方要求

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

required by services服务要求

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

在此处输入图像描述

In your launcher activity, declare "android: exported":在您的启动器活动中,声明“android:exported”:

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

If true “android: exported= true” it means the activity is accessible to any app and can be launched by its exact class name.如果为真“android:exported=true”,则意味着任何应用都可以访问该活动,并且可以通过其确切的 class 名称启动该活动。

If false “android: exported = false” it means the activity can be launched only by the components of the same application with the same user ID, or privileged system components.如果为 false “android:exported = false”,则表示该活动只能由具有相同用户 ID 的同一应用程序的组件或特权系统组件启动。

For more details check here .有关更多详细信息,请查看此处

Update version of androidTestImplementation 'androidx.test.ext:junit:1.1.1' to latest version like: - androidTestImplementation 'androidx.test.ext:junit:1.1.3' from build.gradle app level . Update version of androidTestImplementation 'androidx.test.ext:junit:1.1.1' to latest version like: - androidTestImplementation 'androidx.test.ext:junit:1.1.3' from build.gradle app level .

Add android:exported="true"添加 android:exported="true"

<receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationActions"/>
        <receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationPublisher"/>
        <receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationBootEventReceiver"
         android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <action android:name="android.intent.action.QUICKBOOT_POWERON" />
                <action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/>
            </intent-filter>
        </receiver>

For me neither of the solution worked, even if I double/tripple checked the "merged manifest" in Android Studio.对我来说,这两个解决方案都不起作用,即使我在 Android Studio 中检查了“合并清单”。 After compiling the project, the error just appeared and I couln't identify the line where the issue was generated.编译项目后,错误刚刚出现,我无法识别生成问题的行。

Solution : make sure you're targeting the latest libraries in your poject.解决方案:确保您的目标是项目中的最新库。 I was using Unity, StartApp and Flurry Analytics.我正在使用 Unity、StartApp 和 Flurry Analytics。 I forgot to update these libraries, and after upgrading them the error disappeared.我忘了更新这些库,升级后错误消失了。 It looks like these libraries used < 31 SDK features.看起来这些库使用了 < 31 个 SDK 功能。

If you're using abandoned libraries, then you should consider replacing them.如果您使用的是废弃的库,那么您应该考虑替换它们。

I was getting this error even when I added android:exported="true" in all activities, receivers etc. The thing that worked for me was to change compileSdkVersion and targetSdkVersion to 30.即使我在所有活动、接收器等中添加android:exported="true"时,我也收到此错误。对我有用的事情是将compileSdkVersiontargetSdkVersion更改为 30。

This will help for 2021 users. 这将对 2021 年的用户有所帮助。

In one of your two build.gradle files you should be able to find the line targetSDK 31. Change that to 30 and then do a gradle sync (a small bar will appear above the main code window where you can click "Sync now") and you should be good to go.在您的两个 build.gradle 文件之一中,您应该能够找到 targetSDK 31 行。将其更改为 30,然后执行 gradle 同步(主代码上方会出现一个小条 Z05B8C74CBD96FBF2DE4C1A352702FBF,您现在可以单击“现在单击”“同步”)应该对 go 好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM