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

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


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, orbroadcast receivers that use intent filters, you must explicitlydeclare the android: exported attribute for these app components.

Warning: If an activity, service, or broadcast receiver uses intentfilters and doesn't have an explicitly-declared value forandroid:exported, your app can't be installed on a device that runsAndroid 12.

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


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>

set 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


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 3rd 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 3rd party dependency and it's not going to be updated soon, I just added a 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