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

174,122

Solution 1

You need to specify android:exported="false" or 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.

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.

Also check when to use true/false for the 'android:exported' value.

Solution 2

In your manifest, add android:exported="true" or android:exported="false " in your default launching activity attribute.

Done! You are all right to run your apps on 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.

Whether the broadcast receiver can receive messages from non-system sources outside its application — "true" if it can, and "false" if not. 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.

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". Otherwise, the default value is "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

Solution 3

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 {
    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". There you can inspect what activity exactly didn't have the "android: exported = false" attribute.

In my case it was because of third-party tools:

build.gradle (: app):

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:

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.

Solution 4

I ran into the same issue after targeting Android 12 in my project.

The problem was the project was quite big, with multiple AndroidManifest.xml files, and android:exported missing in many places.

I ended up creating a Gradle task to fill the missing android:exported attributes automatically for me.

Here is the link.

Solution 5

Your question may have flagged for duplication because of this post: Manifest merger failed targeting Android 12, although yours was posted a week earlier. 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.

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

For other activities with intents buried in your merged manifests, this would normally be set to false.

Share:
174,122

Related videos on Youtube

DSF.Inc
Author by

DSF.Inc

Updated on April 12, 2022

Comments

  • DSF.Inc
    DSF.Inc about 2 years

    I have updated my emulator version and Android SDK version to Android S (Android 12). After the update, I cannot run the project. I cannot run a Hello, World! project (empty project), but I can build Gradle as well as, but I can not run the project. 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. See https://developer.android.com/guide/topics/manifest/activity-element#exported for details.

    How can I fix it?

    Here is a screenshot:

    This is a screenshot.

    How can I solve this issue when using 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.

    • ianhanniballake
      ianhanniballake about 3 years
      So...does your AndroidManifest.xml have every component with an <intent-filter> explicitly have the android:exported attribute set? Please include your entire AndroidManifest.xml.
    • Stan
      Stan about 3 years
      I have the same problem, even though I've defined "android:exported" for all activities that have a <intent-filter>, and also for all receivers and providers.
    • Jacob Ras
      Jacob Ras about 3 years
      @Stan I ran into the same issue. Use the "Merged Manifest" view to check the end result of your merged manifest to see if any of the components there are missing the exported value. In my case I had an activity declared in a separate manifest that was missing the exported property. You might need to temporarily downgrade your target SDK back to 30 so that the merged manifest compiles.
    • Jan
      Jan about 3 years
      I was able to debug the issue by following steps here: stackoverflow.com/a/67668116/3274125
    • Renascienza
      Renascienza almost 3 years
      What if the "wrong" manifest comes from a library that I don't have control? I have to build from sources after fix it myself? Google, please stop to be dumb and don't make this kind of requirement, just put a default value and a big warning.
    • kuzdu
      kuzdu almost 3 years
      Hey Renascienza, you have to update to the current version. See the answer before. If this does not help, it's a deadlock. You have to downgrade to compile version 30, add an issue ticket.
    • Alix
      Alix almost 3 years
      Does this answer your question? Manifest merger failed targeting Android 12
    • Rik
      Rik over 2 years
      I experienced this issue when trying to run tests during (navigation/testing in compose) codelabs. I ran ./gradlew processDebugAndroidTestManifest --debug, by typing the aforementioned command into the android studio built-in terminal. Scrolling up in the log let me find the culprit. For me, it was espresso-contrib and espresso-core. Pressing ctrl+alt+shift+s, selecting Dependencies, and then selecting the highest available version (which at the time of this, was 3.5.0-alpha03), resolved the problem after following up with Apply and Ok.
    • Sachin Rajput
      Sachin Rajput about 2 years
      I recently migrated my apps to android 12, and yes i faced all of these issues, here is the migration journey solution : medium.com/native-mobile-bits/…
  • Marc Calandro
    Marc Calandro almost 3 years
    You need to specify ONLY android:exported. But depending on your use case you can set it to true or false
  • Mohit Lakhanpal
    Mohit Lakhanpal almost 3 years
    @MarcCalandro I follow up on all the steps and also include exported = true but the same error occure. Any suggestions..?
  • Alix
    Alix almost 3 years
    Yeah, I don't understand why this was accepted as a solution. I have put android:exported on every single activity with/without intent-filter. Still doesn't work. So likely caused by a dependency somehow.
  • Alix
    Alix almost 3 years
    Doesn't work for me. Looks like some of us have this issue through 3rd party libraries in which case this won't solve it.
  • Alix
    Alix almost 3 years
    This solved it for me: stackoverflow.com/a/67668116/1859486
  • Alexa289
    Alexa289 almost 3 years
    thanks @Alix for pointing me to this stackoverflow.com/a/67668116/1859486 . if you still failed then you also need to add android:exported to your receiver stackoverflow.com/a/68605049/9101876
  • Alexander Bernat
    Alexander Bernat almost 3 years
    Thank you so much! Your script helped me to detect some activities inside androidx.test.core-1.3.0 that had not this property. Even after that there was not an easy task to remove this library dependency from the project... I see how androidx developers are ready for Android 12...
  • Luke Simpson
    Luke Simpson over 2 years
    This! Thanks, Leak Canary needs to be updated to 2.7 in order to target Android 12 (31).
  • neronovs
    neronovs over 2 years
    If the reason is external library, then we can do nothing? Only to ask an owner of the ext-lib to fix it on their side?
  • Xavier Vega
    Xavier Vega over 2 years
    Actually there is, explicitly we added an activity and intent filter that overrode the declared in the dependency (see my edited comment). In my case I added a separate AndroidManifest.xml to the src/debug folder since I need that dependency only for debug.
  • mihirjoshi
    mihirjoshi over 2 years
    how to debug the problem is a great advice
  • Selmeny
    Selmeny over 2 years
    The only solution that works! Thank you.
  • LeoFarage
    LeoFarage over 2 years
    You don't need to override completely the activity entry. You can use the tools:node="merge" attribute and declare the android:exported=true|false. This should add the property to the target Activity in the final merged AndroidManifest. Check this link on how to handle manifests in the project: developer.android.com/studio/build/manage-manifests
  • morfair
    morfair over 2 years
    Where is "main manifest.xml window"? For Flutter project.
  • Kyriakos Xatzisavvas
    Kyriakos Xatzisavvas over 2 years
    This should have more upvotes. Saved me a lot of hassle
  • russellhoff
    russellhoff over 2 years
    In my case, I only had to set exported='true' within the launcher activity. For the rest of the activities was not necessary to establish it to false.
  • ice_chrysler
    ice_chrysler over 2 years
    Thank you for this very helpful answer. Unfortunately in my (rather large) project the MergedManifest view did not work and showed an empty screen. However you can simply find the merged manifest after a successful build in your output directory, i.e. something like app/build/intermediates/merged_manifests/debug/AndroidManife‌​st.xml. Simply search this file for <intent-filter> tags. In my case an external library declared an Activity with an intent-filter but missed the exported flag. Updating this library to the latest version fixed the issue for me.
  • chrisfey
    chrisfey over 2 years
    There is a gradle script written by @DatPhamTat here: stackoverflow.com/a/68786768/2019414 That is very very helpful and will automatically update all your manifest files with the exported flags
  • Noah
    Noah over 2 years
    A downgrade is not an option in android development. Remove this answer
  • Noah
    Noah over 2 years
    A downgrade is not an option in android development. Remove this answer
  • STEEL
    STEEL over 2 years
    thanks this helped me in LibGDX project :) android:exported="true"
  • Ali Azimoshan
    Ali Azimoshan over 2 years
    in my case, I have to add android:exported="true" to all my <receiver> tag too.
  • Maude
    Maude over 2 years
    The downgrade version is in fact the only solution that seems to work for projects with 1 activity, that don't have a <receiver> and that already have the appropriate exported tag.
  • Bugs Happen
    Bugs Happen over 2 years
    Both tasks were executed successfully and said Hooray, your AndroidManifest.xml did not need any change. but I still get the same error of android:exported missing.
  • Raii
    Raii about 2 years
    @Alexa289 do you know how to use it? I know a normal Android Project will have 2 build.gradle(App & Module). I didn't see some function inside the build.gradle before. The link you post that provide build.gradle at github doesn't contain Android Studio generated build.gradle items so I am a bit confused.
  • Shesh Narayan Deshmukh
    Shesh Narayan Deshmukh about 2 years
    thanks it needed to update compileSdkVersion & targetSdkVersion