Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Manifest merger failed : Apps targeting Android 12 - Android Studio Error [duplicate]

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.

like image 502
DSF.Inc Avatar asked May 06 '21 05:05

DSF.Inc


People also ask

How do I fix a failed manifest merger?

The initial process would be to open the manifest application known as the AndroidManifest. xml and then click on the Merged Manifest tab below your edit pane. Following which, Click on the merged manifest option. An Error would be visible at the right column and then one must try to solve the error.

Where is the manifest file in Android Studio?

The file is located at WorkspaceName>/temp/<AppName>/build/luaandroid/dist. The manifest file provides essential information about your app to the Android operating system, and Google Play store. The Android manifest file helps to declare the permissions that an app must have to access data from other apps.

What is manifest file in APK?

The manifest file describes essential information about your app to the Android build tools, the Android operating system, and Google Play.


Video Answer


11 Answers

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

like image 25
Shihab Uddin Avatar answered Oct 17 '22 11:10

Shihab Uddin


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.

like image 187
Mittal Varsani Avatar answered Oct 17 '22 11:10

Mittal Varsani


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.

like image 26
Xavier Vega Avatar answered Oct 17 '22 12:10

Xavier Vega


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.

like image 41
Dat Pham Tat Avatar answered Oct 17 '22 13:10

Dat Pham Tat


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.

like image 38
Androidcoder Avatar answered Oct 17 '22 11:10

Androidcoder


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

like image 38
Noah Avatar answered Oct 17 '22 11:10

Noah


Notes

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:enabled="true" />
like image 38
Heri moradiya Avatar answered Oct 17 '22 13:10

Heri moradiya


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" />
like image 28
Rehan Khan Avatar answered Oct 17 '22 12:10

Rehan Khan


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.

like image 28
Richard Kamere Avatar answered Oct 17 '22 12:10

Richard Kamere


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>
like image 45
Soumik Chakraborty Avatar answered Oct 17 '22 12:10

Soumik Chakraborty


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.

like image 20
ATA UR RAHMAN Avatar answered Oct 17 '22 12:10

ATA UR RAHMAN