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

This question already has answers here:
android:exported needs to be explicitly specified for <activity>. Apps targeting Android 12 and higher are required to specify
(35 answers)
Closed 4 months ago.
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:
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.

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.

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

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.

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.

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

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

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.

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

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.

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>

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.

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.

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.

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.

Related

how to fix a running proplem android

This problem is faced when I am copying another copy of a project that is similar by name and on the same disk but after a few seconds I noticed this and cancel the operation of copying the other project, unfortunately, it seems to override some of the files in the first project
Error message when Running the first project :
The application could not be installed: INSTALL_PARSE_FAILED_MANIFEST_MALFORMED
The application could not be installed: INSTALL_PARSE_FAILED_MANIFEST_MALFORMED
List of apks:
[0] 'C:\Users\hp\Desktop\TrafficAccident\app\build\outputs\apk\debug\app-debug.apk'
Installation failed due to: 'null'
How to fix it?
In manifest file add android:exported="true" in the launcher activity tag
<activity
android:name=".MainActivity"
android:alwaysRetainTaskState="true"
android:configChanges="orientation|screenSize"
android:exported="true"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

App not receiving boot completed intent in some devices

i created an app that always start a service once the device has completed booting.
This is the Manifest code..
<receiver>
android:name="StartMyServiceAtBootReceiver"
android:directBootAware ="true"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
<action android:name="android.intent.action.REBOOT"/>
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
</intent-filter>
</receiver>
The service always start in some devices once boot is completed but in my own device which is running android 7.0, the boot completed service doesn't start unless i convert the app to system app using root access. Can someone tell me how to make the app to start the service on boot completed without converting it to a system app?
First of All
receiver android:name="StartMyServiceAtBootReceiver"
Your path to Receiver should written over here for example:
<receiver android:name=".receiver.BootReceiver">
first dot suggest your path till root of the package.
Create a BroadcastReceiver and register it to receive ACTION_BOOT_COMPLETED. You also need RECEIVE_BOOT_COMPLETED permission.
Read: Listening For and Broadcasting Global Messages , and Setting Alarms
Try into manifest
<receiver
android:name=".AutoStart"
android:enabled="true"
android:exported="true" >
<intent-filter android:priority="500" >
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
Make sure also to include the completed boot permission.
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
Also read this answer carefully

Manifest-declared broadcast receiver does not receive custom broadcast on Android 8

First, I created a BroadcastReceiver with empty body. Then, I added it to the AndroidManifest.xml. But I found out that BroadcastReceiver declared in manifest does not receive any broadcast. I sent broadcast by
sendOrderedBroadcast(new Intent("com.example.action"), null)
or
adb shell am broadcast -a com.example.action
Both methods works on Android 7 but it does not work on Android 8. However, if the BroadcastReceiver is declared through registerReceiver, then it can still receive the broadcast.
On the other hand, android.hardware.usb.action.USB_DEVICE_ATTACHED works fine on both Android 7 and 8.
I want to ask why does it happen? I have tested it in both emulator and a physical device. They have the same behavior.
AndroidManifest.xml
...
<receiver
android:name=".device.UsbBroadcastReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
<action android:name="com.example.action" />
</intent-filter>
<meta-data
android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
android:resource="#xml/device_filter" />
</receiver>
...
As part of the Android 8.0 (API level 26) Background Execution Limits, apps that target the API level 26 or higher can no longer register broadcast receivers for implicit broadcasts in their manifest.
Read this
Manifest Based broadcast working for me in android 8
Broadcast restriction by android is not applicable for all the broadcasts some can still be registered inside manifest . But do check latest documentation since these may way depending on android version .
<receiver
android:name=".UsbReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
</intent-filter>
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_DETACHED" />
</intent-filter>
<meta-data
android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
android:resource="#xml/device_filter" />

Manifest Merger Failed When Trying to Update to Latest FirebaseUI

I am trying to add the latest FirebaseUI dependency to my Android project. I have Facebook login enabled in my project, and when I set up the Facebook login I was required to add my Facebook App ID in the Android manifest. Here is the dependency I added to my android project:
"com.firebaseui:firebase-ui:3.0.0"
After compiling, I received the following error:
Error:Execution failed for task ':app:processDebugManifest'.
Manifest merger failed : Attribute meta-data#com.facebook.sdk.ApplicationId#value value=() from AndroidManifest.xml:29:13-52
is also present at [com.firebaseui:firebase-ui-auth:3.0.0] AndroidManifest.xml:21:13-60 value=().
Suggestion: add 'tools:replace="android:value"' to element at AndroidManifest.xml:27:9-29:55 to override.
I am not sure why I am being prompted to change my Facebook App ID in order to use the latest library. I am updating so that I can take advantage of the new FirebaseUI features and Firebase Cloud Firestore as well.
Manifest
<uses-permission android:name="android.permission.INTERNET" />
<application
android:name="android.support.multidex.MultiDexApplication"
android:allowBackup="true"
android:icon="#drawable/xxxxxxx"
android:label="#string/xxxxxxx"
android:theme="#style/AppTheme.NoActionBar"> <!-- ADD THIS LINE -->
<activity
android:name=".SignupActivity"
android:screenOrientation="portrait"
android:theme="#style/AppTheme.NoActionBar"
android:windowSoftInputMode="adjustPan" />
<activity
android:name="com.facebook.FacebookActivity"
android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"
android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar"
tools:replace="android:theme" />
<meta-data
android:name="com.facebook.sdk.ApplicationId"
android:value="#string/facebook_app_id" />
<meta-data
android:name="com.firebase.ui.GoogleClientId"
android:value="#string/google_client_id" />
<meta-data
android:name="com.firebase.ui.TwitterKey"
android:value="#string/twitter_app_key" />
<meta-data
android:name="com.firebase.ui.TwitterSecret"
android:value="#string/twitter_app_secret" />
<activity
android:name=".PollHostActivity"
android:label="#string/title_activity_poll"
android:launchMode="singleTask"
android:screenOrientation="portrait"
android:theme="#style/AppTheme.NoActionBar"
android:windowSoftInputMode="adjustPan" />
<activity
android:name=".LoadingActivity"
android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".HomeActivity"
android:screenOrientation="portrait" />
<activity
android:name=".CreateActivity"
android:screenOrientation="portrait"
android:theme="#style/AppTheme.NoActionBar" />
<activity
android:name=".NewImageActivity"
android:theme="#style/AppTheme">
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data
android:name="android.app.searchable"
android:resource="#xml/searchable" />
</activity>
<activity
android:name=".ProfileActivity"
android:label="#string/title_activity_profile"
android:theme="#style/AppTheme.NoActionBar"></activity>
</application>
Your post says: when I set up the Facebook login I was required to add my Facebook App ID in the Android manifest. That is not the case for firebase-ui-auth:3.1.0 and may not be for 3.0.0 either. With 3.1.0, you define the IDs as string resources, as described here, and FirebaseUI generates the needed manifest entries, which get merged into the main manifest at build time. If you are defining the constants in your manifest manually, that is likely the cause of the merge conflict.
To see the contributors to the merged manifest, open your AndroidManifest.xml file in Android Studio. Click the Merged Manifest tab at the bottom of the window. In the right pane, find and click on firebase-ui-auth:3.0.0 to see the manifest entries that are generated by FirebaseUI for merging into the composite manifest. If you see meta-data entries there that you have manually entered into your manifest, delete your entries to eliminate the merge conflict.
Try following their GitHub readme, located here. I was having the same problem as well and my question got a lot of attention but unluckily none could pin point the problem. The problem lies somewhere in the gradle file where you are writing this "com.firebaseui:firebase-ui:3.0.0".

Installing Android app in a device

I'm a newbie programming for android, I made a simple game some days ago and I tried to install it in a tablet(Android 4.0).
The program works ok, but I got four(4) icons of my app after installation and only one of them is correct(third).
I just want to know how I can to solve this bug so that when I install it in another device it runs ok and get only one icon.
Thanks in advance.
It's because in your manifest you need to change all of your activities EXCEPT your first activity (usually your mainActivity) from:
<activity
android:name=".SecondActivity"
android:label="activity name" >
<intent-filter
android:label="Your App Name">
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
to:
<activity
android:name=".SecondActivity"
android:label="activity name" >
</activity>
Basically just take the intent-filter out of all your activities that are NOT your main activity. Your main activity needs it so that there is a launcher icon. Hope that helps.
I got four(4) icons of my app after installation
means you have declared more then one Activity in AndroidManifest.xml as launch Activity. to show only one Activity as launcher you will need to declare only one Activity with android.intent.action.MAIN and android.intent.category.LAUNCHER intent-filter.
Declare Main Activity which u want to show in Launcher as:
<activity android:name="MainActvity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
and other 3 Activity declare as in AndroidManifest.xml as :
<activity android:name="Actvity_Two"
android:label="#string/app_name" />
<activity android:name="Actvity_Three"
android:label="#string/app_name" />
//declare other in same way ..

Categories

Resources