Android Studio error: "Manifest merger failed: Apps targeting Android 12" [duplicate]
Asked Answered
C

14

302

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.

Comitia answered 6/5, 2021 at 5:0 Comment(11)
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.Wrecker
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.Spirituality
@Spirituality 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.Repute
I was able to debug the issue by following steps here: https://mcmap.net/q/101714/-manifest-merger-failed-targeting-android-12-duplicateEisteddfod
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.Pak
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.Christy
Does this answer your question? Manifest merger failed targeting Android 12Leanto
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.Guyenne
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/…Bock
Having the error in a library "com.android.library" that I created, no activities :(, someone already solved this?.Jericajericho
"Merged Manifest" view is the key to debug! thank you @JacobRasSchade
I
435

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.

Infective answered 6/5, 2021 at 5:25 Comment(11)
You need to specify ONLY android:exported. But depending on your use case you can set it to true or falseSamiel
@MarcCalandro I follow up on all the steps and also include exported = true but the same error occure. Any suggestions..?Showcase
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.Leanto
This solved it for me: https://mcmap.net/q/101714/-manifest-merger-failed-targeting-android-12-duplicateLeanto
thanks @Leanto for pointing me to this https://mcmap.net/q/101714/-manifest-merger-failed-targeting-android-12-duplicate . if you still failed then you also need to add android:exported to your receiver https://mcmap.net/q/99654/-android-studio-error-quot-manifest-merger-failed-apps-targeting-android-12-quot-duplicateJokester
There is a gradle script written by @DatPhamTat here: https://mcmap.net/q/99654/-android-studio-error-quot-manifest-merger-failed-apps-targeting-android-12-quot-duplicate That is very very helpful and will automatically update all your manifest files with the exported flagsTasia
thanks this helped me in LibGDX project :) android:exported="true"Scalf
in my case, I have to add android:exported="true" to all my <receiver> tag too.Aleksandrovsk
@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.Syllabi
add this property in android:exported="true" in <activity android:name=".MainActivity" android:exported="true" this can resolve your issueReenter
This did not work for me. Apparently the issue was with this plugin : flutter_local_notifications: ^6.0.0 . I had to disable all plugins and enable each one one my one to figure it out ....Tune
T
74

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

Tomb answered 19/7, 2021 at 6:45 Comment(1)
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.Leanto
S
59

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:

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

Shayn answered 27/9, 2021 at 13:23 Comment(13)
This! Thanks, Leak Canary needs to be updated to 2.7 in order to target Android 12 (31).Ardys
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?Workwoman
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.Shayn
The only solution that works! Thank you.Monaxial
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-manifestsCermet
Where is "main manifest.xml window"? For Flutter project.Popple
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.Whiney
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/AndroidManifest.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.Chalcography
thanks it needed to update compileSdkVersion & targetSdkVersionSubmergible
@user2350644. what you suggested app/build/intermediates/merged_manifests/debug/AndroidManifest.xml that worked for me thanks. I have checked inside this Androidmanifest.xml file there in one activity was missing exported flag. ThanksWive
You are correct- it could be a problem with a dependancy. Personally I think there are more efficient ways of doing this though. Just go to your manifest file and click the 'merged manifest' tab at the bottom. This will show you the error of the exact dependancy(s) that are causing the problem. You may have to click through all the jetified manifests to double check the exact dependancy that matches the error. After that you're probably better off just updating the offending dependancies as they're clearly not designed for api 31 anyhow.Loudmouth
Thanks! This fixed the problem for me in my case problem was in razorpay 1.5.16. I updated the version and then fixed.Salbu
The leakcanary clue save my day, brilliant!Enclosure
K
29

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.

Katricekatrina answered 14/8, 2021 at 20:23 Comment(5)
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...Wampler
This should have more upvotes. Saved me a lot of hassleSeedling
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.Mirza
It didn't help. Can you please write complete step by step guide how to use this task?Whacky
May the god force be with you. This was by far the fastest way to debug the issue. Should be the approved answer.Auriscope
T
23

The android:exported attribute sets whether a component (activity, service, broadcast receiver, etc.) can be launched by components of other applications:

  • If true, any app can access the activity and launch it by its exact class name.
  • If false, only components of the same application, applications with the same user ID, or privileged system components can launch the activity.

The logic behind the default value of this attribute changed over time and was different depending on the component types and Android versions. For example, on API level 16 (Android 4.1.1) or lower the value for elements is set to true by default. Not setting this attribute explicitly carries the risk of having different default values between some devices.

Taken from the official documentation

Things changed since Android 12 devices, so you need to do these things:

Add android:exported="true" to all receivers declared in the manifest.

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

Also for Activities (the one that would be launched by Android OS A.K.A Launcher activity)

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

Note: For Services and Broadcast Receivers that use intent filters, you must explicitly declare the android: exported attribute.

Don't just add android:exported="true" to just everything. Cases where the Broadcast receivers need to be visible to Android OS, are examples where where you might want to specify android:exported. The Intent filters in that code mean I wanted Android OS to wake up my Android app and perform an operation.

android.intent.action.BOOT_COMPLETED is a very good example because Android OS sends broadcasts to every application installed in the device. So technically, it would mean that any Broadcast receiver that has an intent filter with actions should always declare android:exported="true".

Theatricalize answered 31/7, 2021 at 19:0 Comment(0)
P
17

For apps targeting Android 12

Change your app's targetSdkVersion to S (32 or 31) to enable the new behavior.

Then specify the android:exported="" attribute in Manifest to either true or false depending on Activity.

For a launcher activity such as splash or MainActivity, use android:exported="true" and for the rest of the Activities, use android:exported="false"

For example:

<!-- 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" />
Preceding answered 20/2, 2022 at 13:10 Comment(0)
M
16

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.

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 receiver

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

</receiver>

Required by services


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

Mamoun answered 25/3, 2022 at 9:5 Comment(0)
J
13

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.

Justajustemilieu answered 18/7, 2021 at 12:57 Comment(0)
E
3

Enter image description here

In your launcher activity, declare "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.

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.

For more details check here.

Engelbert answered 14/9, 2021 at 20:7 Comment(1)
Both true and false solutions not worked for me. Thanks for your efforts.Dierdre
P
3

Update the version of androidTestImplementation 'androidx.test.ext:junit:1.1.1' to the latest version, like:

androidTestImplementation 'androidx.test.ext:junit:1.1.3' from the build.gradle app level.

Polygamous answered 4/2, 2022 at 10:58 Comment(0)
Z
2

Add 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>
Zellers answered 1/7, 2022 at 5:13 Comment(2)
The accepted answer tells the same thing. Please edit your answer, so that it gives a different solution altogether, or remove it.Lie
But it is missing the end tag "</receiver>"(?).Electronic
C
0

For me neither of the solutions worked, even if I double/triple checked the "merged manifest" in Android Studio. After compiling the project, the error just appeared and I couldn’t identify the line where the issue was generated.

Solution: make sure you're targeting the latest libraries in your project. I was using Unity, StartApp and Flurry Analytics. I forgot to update these libraries, and after upgrading them, the error disappeared. It looks like these libraries used features from before SDK 31.

If you're using abandoned libraries, then you should consider replacing them.

Calabar answered 23/6, 2022 at 17:40 Comment(1)
The merged manifest tab contains a bunch of hyperlinks to all the manifests being generated in your project. From there you can click on each one find the one with the intent filter for activity or receiver that doesn't have the exported flag set.Loudmouth
M
-3

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.

Marvismarwin answered 28/9, 2021 at 12:47 Comment(3)
A downgrade is not an option in android development. Remove this answerTheatricalize
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.Foch
Then the app will never be accepted in Google play store because that violates their policyTheatricalize
G
-11

This will help for 2021 users.

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.

Gary answered 24/8, 2021 at 9:42 Comment(2)
A downgrade is not an option in android development. Remove this answerTheatricalize
The app will never be accepted in Google play store because that violates their policyTheatricalize

© 2022 - 2024 — McMap. All rights reserved.