287

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
DSF.Inc
  • 3,021
  • 2
  • 6
  • 9
  • 7
    So...does your `AndroidManifest.xml` have every component with an `` explicitly have the `android:exported` attribute set? Please include your entire `AndroidManifest.xml`. – ianhanniballake May 06 '21 at 05:06
  • 20
    I have the same problem, even though I've defined "android:exported" for all activities that have a , and also for all receivers and providers. – Stan May 11 '21 at 14:30
  • 6
    @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. – Jacob Ras May 24 '21 at 10:16
  • 8
    I was able to debug the issue by following steps here: https://stackoverflow.com/a/67668116/3274125 – Jan May 27 '21 at 09:00
  • 3
    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. – Renascienza Aug 18 '21 at 22:02
  • 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. – kuzdu Aug 19 '21 at 12:24
  • 2
    Does this answer your question? [Manifest merger failed targeting Android 12](https://stackoverflow.com/questions/67654506/manifest-merger-failed-targeting-android-12) – Alix Sep 14 '21 at 07:41
  • 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*. – Rik Nov 28 '21 at 03:21
  • I recently migrated my apps to android 12, and yes i faced all of these issues, here is the migration journey solution : https://medium.com/native-mobile-bits/lets-use-android-12-migration-of-our-android-apps-to-android12-api-31-af329b6829d0 – Sachin Rajput Apr 12 '22 at 16:19
  • Having the error in a library "com.android.library" that I created, no activities :(, someone already solved this?. – Akhha8 Jun 01 '22 at 23:28
  • "Merged Manifest" view is the key to debug! thank you @JacobRas – Dmitry Salnikov Oct 20 '22 at 14:42

14 Answers14

404

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.

Sami
  • 295
  • 2
  • 6
  • 10
Mittal Varsani
  • 5,601
  • 2
  • 15
  • 27
  • 3
    You need to specify ONLY android:exported. But depending on your use case you can set it to true or false – Marc Calandro Jul 08 '21 at 02:59
  • 54
    @MarcCalandro I follow up on all the steps and also include exported = true but the same error occure. Any suggestions..? – Mohit Lakhanpal Sep 03 '21 at 06:56
  • 15
    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 Sep 14 '21 at 07:25
  • 3
    This solved it for me: https://stackoverflow.com/a/67668116/1859486 – Alix Sep 14 '21 at 07:40
  • 2
    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 https://stackoverflow.com/a/68605049/9101876 – Alexa289 Sep 16 '21 at 07:40
  • There is a gradle script written by @DatPhamTat here: https://stackoverflow.com/a/68786768/2019414 That is very very helpful and will automatically update all your manifest files with the exported flags – chrisfey Jan 14 '22 at 10:40
  • thanks this helped me in LibGDX project :) `android:exported="true"` – STEEL Feb 05 '22 at 04:33
  • in my case, I have to add ```android:exported="true"``` to all my `````` tag too. – Ali Azimoshan Feb 14 '22 at 08:11
  • @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. – Raii Apr 05 '22 at 01:40
  • add this property in android:exported="true" in – Jamal Basha Nov 09 '22 at 13:10
  • 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 .... – crushman Nov 13 '22 at 20:45
73

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

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Shihab Uddin
  • 6,699
  • 2
  • 59
  • 74
  • 14
    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 Sep 14 '21 at 07:26
57

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Xavier Vega
  • 701
  • 5
  • 6
  • This! Thanks, Leak Canary needs to be updated to 2.7 in order to target Android 12 (31). – Luke Simpson Oct 01 '21 at 10:06
  • 1
    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? – neronovs Oct 08 '21 at 11:38
  • 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. – Xavier Vega Oct 11 '21 at 08:55
  • The only solution that works! Thank you. – Selmeny Nov 15 '21 at 04:17
  • 6
    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: https://developer.android.com/studio/build/manage-manifests – LeoFarage Nov 18 '21 at 13:26
  • Where is "main manifest.xml window"? For Flutter project. – morfair Nov 19 '21 at 15:02
  • 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. – joninx Nov 23 '21 at 11:50
  • 3
    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 `` 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. – ice_chrysler Dec 06 '21 at 12:01
  • thanks it needed to update compileSdkVersion & targetSdkVersion – Shesh Narayan Deshmukh Apr 28 '22 at 06:02
  • @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. Thanks – user2162130 Jul 28 '22 at 09:34
  • 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. – Reece Nov 24 '22 at 18:41
  • Thanks! This fixed the problem for me in my case problem was in razorpay 1.5.16. I updated the version and then fixed. – Shashank Pandey Feb 24 '23 at 09:26
28

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Dat Pham Tat
  • 1,433
  • 7
  • 9
  • 1
    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... – Alexander Bernat Sep 20 '21 at 16:44
  • 1
    This should have more upvotes. Saved me a lot of hassle – Kyriakos Xatzisavvas Nov 19 '21 at 16:19
  • 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. – Bugs Happen Feb 15 '22 at 13:41
  • 1
    It didn't help. Can you please write complete step by step guide how to use this task? – Mohit Rajput Sep 28 '22 at 12:15
  • May the god force be with you. This was by far the fastest way to debug the issue. Should be the approved answer. – Mohammed Uzair Nov 02 '22 at 12:02
19

I had to also add android:exported="true" to all my receivers declared in the manifest. 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. You should only add that when those Broadcast receivers need to be visible to Android OS. The Intent filters in that code mean that 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".

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Noah
  • 567
  • 5
  • 21
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" />
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Rehan Khan
  • 1,031
  • 13
  • 10
15

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

Tombstone
  • 208
  • 2
  • 5
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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Androidcoder
  • 4,389
  • 5
  • 35
  • 50
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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Richard Kamere
  • 749
  • 12
  • 10
1

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Zbarcea Christian
  • 9,367
  • 22
  • 84
  • 137
  • 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. – Reece Nov 24 '22 at 18:43
0

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>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
-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.

Ashwani Kumar
  • 1,402
  • 1
  • 19
  • 26
  • 1
    A downgrade is not an option in android development. Remove this answer – Noah Feb 04 '22 at 05:37
  • The downgrade version is in fact the only solution that seems to work for projects with 1 activity, that don't have a and that already have the appropriate exported tag. – Maude Feb 14 '22 at 18:19
-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.