After upgrading to android 12, the application is not compiling. It shows
“Manifest merger failed with multiple errors, see logs”
Error showing in Merged manifest:
Merging Errors: Error: android:exported needs to be explicitly specified for . 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. main manifest (this file)
I have set all the activity with android:exported="false"
. But it is still showing this issue.
My manifest file:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="eu.siacs.conversations"> <uses-sdk tools:overrideLibrary="net.ypresto.androidtranscoder" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_CONTACTS" /> <uses-permission android:name="android.permission.READ_PROFILE" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" android:maxSdkVersion="22" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" /> <uses-feature android:name="android.hardware.location" android:required="false" /> <uses-feature android:name="android.hardware.location.gps" android:required="false" /> <uses-feature android:name="android.hardware.location.network" android:required="false" /> <uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /> <uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" /> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <uses-feature android:name="android.hardware.camera" android:required="false" /> <uses-feature android:name="android.hardware.camera.autofocus" android:required="false" /> <uses-feature android:name="android.hardware.microphone" android:required="false" /> <application android:name=".Application" android:allowBackup="false" android:allowClearUserData="true" android:appCategory="social" android:hardwareAccelerated="true" android:icon="@mipmap/ic_app_launch" android:label="@string/app_name" android:largeHeap="true" android:networkSecurityConfig="@xml/network_security_configuration" android:requestLegacyExternalStorage="true" android:roundIcon="@mipmap/ic_app_launch_round" android:theme="@style/ConversationsTheme" android:usesCleartextTraffic="true" android:windowSoftInputMode="adjustPan|adjustResize" tools:replace="android:label" tools:targetApi="q"> <activity android:name=".ui.search.GroupSearchActivity" android:exported="true" /> <activity android:name=".ui.profileUpdating.FavouritesActivity" android:exported="true" /> <activity android:name=".ui.profileUpdating.NameActivity" android:exported="true" /> <activity android:name=".ui.CompulsoryUpdateActivity" android:exported="true" /> <activity android:name=".ui.payments.doPayment.DoPaymentActivity" android:exported="true" /> <activity android:name=".ui.individualList.IndividualListActivity" android:exported="true" /> <activity android:name=".ui.payments.setPayment.SetPaymentActivity" android:exported="true" /> <activity android:name=".ui.login.otpActivity.OTPActivity" android:exported="true" /> <activity android:name=".ui.login.loginActivity.LoginActivity" android:exported="true" /> <service android:name=".services.XmppConnectionService" android:exported="true" /> <receiver android:name=".services.EventReceiver" android:exported="true"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> <action android:name="android.intent.action.ACTION_SHUTDOWN" /> <action android:name="android.media.RINGER_MODE_CHANGED" /> </intent-filter> </receiver> <activity android:name=".ui.ShareLocationActivity" android:label="@string/title_activity_share_location" android:exported="true"/> <activity android:name=".ui.SearchActivity" android:label="@string/search_messages" android:exported="true" /> <activity android:name=".ui.RecordingActivity" android:configChanges="orientation|screenSize" android:theme="@style/ConversationsTheme.Dialog" android:exported="true" /> <activity android:name=".ui.ShowLocationActivity" android:label="@string/title_activity_show_location" android:exported="true" /> <activity android:name=".ui.SplashActivity" android:theme="@style/SplashTheme" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".ui.ConversationsActivity" android:label="@string/app_name" android:launchMode="singleTask" android:minWidth="300dp" android:minHeight="300dp" android:exported="true" android:windowSoftInputMode="stateHidden" /> <activity android:name=".ui.ScanActivity" android:screenOrientation="portrait" android:exported="true" android:theme="@style/ConversationsTheme.FullScreen" android:windowSoftInputMode="stateAlwaysHidden" /> <activity android:name=".ui.UriHandlerActivity" android:label="@string/app_name" android:exported="true"> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="xmpp" /> </intent-filter> <intent-filter android:autoVerify="true"> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="https" /> <data android:host="im.app.in" /> <data android:pathPrefix="/i/" /> <data android:pathPrefix="/j/" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.SENDTO" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="imto" /> <data android:host="jabber" /> </intent-filter> </activity> <activity android:name=".ui.StartConversationActivity" android:label="@string/title_activity_start_conversation" android:launchMode="singleTop" android:exported="true"> <intent-filter> <action android:name="android.intent.action.VIEW" /> </intent-filter> </activity> <activity android:name=".ui.SettingsActivity" android:label="@string/title_activity_settings" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.NOTIFICATION_PREFERENCES" /> </intent-filter> </activity> <activity android:name=".ui.ChooseContactActivity" android:label="@string/title_activity_choose_contact" android:exported="true" /> <activity android:name=".ui.BlocklistActivity" android:label="@string/title_activity_block_list" android:exported="true"/> <activity android:name=".ui.ChangePasswordActivity" android:label="@string/change_password_on_server" android:exported="true"/> <activity android:name=".ui.ChooseAccountForProfilePictureActivity" android:enabled="false" android:label="@string/choose_account" android:exported="true"> <intent-filter android:label="@string/set_profile_picture"> <action android:name="android.intent.action.ATTACH_DATA" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="image/*" /> </intent-filter> </activity> <activity android:name=".ui.ShareViaAccountActivity" android:label="@string/title_activity_share_via_account" android:launchMode="singleTop" android:exported="true" /> <activity android:name=".ui.EditAccountActivity" android:launchMode="singleTop" android:exported="true" android:windowSoftInputMode="stateHidden|adjustResize" /> <activity android:name=".ui.ConferenceDetailsActivity" android:label="@string/action_muc_details" android:exported="true" android:windowSoftInputMode="stateHidden" /> <activity android:name=".ui.ContactDetailsActivity" android:exported="true" android:windowSoftInputMode="stateHidden" /> <activity android:name=".ui.PublishProfilePictureActivity" android:label="@string/mgmt_account_publish_avatar" android:exported="true" android:windowSoftInputMode="stateHidden" /> <activity android:name=".ui.PublishGroupChatProfilePictureActivity" android:exported="true" android:label="@string/group_chat_avatar" /> <activity android:name=".ui.ShareWithActivity" android:label="@string/app_name" android:launchMode="singleTop" android:exported="true"> <intent-filter> <action android:name="android.intent.action.SEND" /> <action android:name="android.intent.action.SEND_MULTIPLE" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="text/plain" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.SEND" /> <action android:name="android.intent.action.SEND_MULTIPLE" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="*/*" /> </intent-filter> <!-- the value here needs to be the full class name; independent of the configured applicationId --> <meta-data android:name="android.service.chooser.chooser_target_service" android:value="eu.siacs.conversations.services.ContactChooserTargetService" /> </activity> <activity android:name=".ui.TrustKeysActivity" android:label="@string/trust_omemo_fingerprints" android:exported="true" android:windowSoftInputMode="stateAlwaysHidden" /> <activity android:name="com.theartofdev.edmodo.cropper.CropImageActivity" android:exported="true" android:theme="@style/Base.Theme.AppCompat" /> <activity android:name=".ui.MemorizingActivity" android:exported="true" /> <activity android:name=".ui.MediaBrowserActivity" android:exported="true" android:label="@string/media_browser" /> <service android:name=".services.ExportBackupService" android:exported="true"/> <service android:name=".services.ImportBackupService" android:exported="true"/> <service android:name=".services.ContactChooserTargetService" android:permission="android.permission.BIND_CHOOSER_TARGET_SERVICE" android:exported="true"> <intent-filter> <action android:name="android.service.chooser.ChooserTargetService" /> </intent-filter> </service> <service android:name=".services.CompulsoryUpdateService" android:exported="true"/> <provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.files" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider> <provider android:name=".services.BarcodeProvider" android:authorities="${applicationId}.barcodes" android:exported="false" android:grantUriPermissions="true" /> <activity android:name=".ui.ShortcutActivity" android:label="@string/contact" android:exported="true"> <intent-filter> <action android:name="android.intent.action.CREATE_SHORTCUT" /> </intent-filter> </activity> <activity android:name=".ui.MucUsersActivity" android:exported="true" android:label="@string/group_chat_members" /> <activity android:name=".ui.ChannelDiscoveryActivity" android:exported="true" android:label="@string/discover_channels" /> <activity android:name=".ui.RtpSessionActivity" android:autoRemoveFromRecents="true" android:exported="true" android:launchMode="singleInstance" android:supportsPictureInPicture="true" /> </application> </manifest>
My second manifest file:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="eu.siacs.conversations"> <application tools:ignore="GoogleAppIndexingWarning"> <activity android:name=".ui.ManageAccountActivity" android:label="@string/title_activity_manage_accounts" android:launchMode="singleTask" android:exported="true"/> <activity android:name=".ui.MagicCreateActivity" android:label="@string/create_new_account" android:launchMode="singleTask" android:exported="true"/> <activity android:name=".ui.EasyOnboardingInviteActivity" android:label="@string/invite_to_app" android:launchMode="singleTask" /> <activity android:name=".ui.ImportBackupActivity" android:label="@string/restore_backup" android:launchMode="singleTask" android:exported="true"> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="application/vnd.conversations.backup" /> <data android:scheme="content" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="application/vnd.conversations.backup" /> <data android:scheme="file" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="content" /> <data android:host="*" /> <data android:mimeType="*/*" /> <data android:pathPattern=".*\.ceb" /> <data android:pathPattern=".*\..*\.ceb" /> <data android:pathPattern=".*\..*\..*\.ceb" /> <data android:pathPattern=".*\..*\..*\..*\.ceb" /> <data android:pathPattern=".*\..*\..*\..*\..*\.ceb" /> <data android:pathPattern=".*\..*\..*\..*\..*\..*\.ceb" /> <data android:pathPattern=".*\..*\..*\..*\..*\..*\..*\.ceb" /> </intent-filter> <intent-filter> <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:host="*" /> <data android:mimeType="*/*" /> <data android:pathPattern=".*\.ceb" /> <data android:pathPattern=".*\..*\.ceb" /> <data android:pathPattern=".*\..*\..*\.ceb" /> <data android:pathPattern=".*\..*\..*\..*\.ceb" /> <data android:pathPattern=".*\..*\..*\..*\..*\.ceb" /> <data android:pathPattern=".*\..*\..*\..*\..*\..*\.ceb" /> <data android:pathPattern=".*\..*\..*\..*\..*\..*\..*\.ceb" /> </intent-filter> </activity> </application> </manifest>
My gradle file:
import com.android.build.OutputFile // Top-level build file where you can add configuration options common to all // sub-projects/modules. buildscript { ext.kotlin_version = "1.5.21" repositories { google() mavenCentral() maven { url 'https://jitpack.io' } gradlePluginPortal() } dependencies { classpath 'com.android.tools.build:gradle:4.2.2' classpath 'com.google.gms:google-services:4.3.8' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply plugin: 'kotlin-kapt' apply plugin: 'com.google.gms.google-services' repositories { google() mavenCentral() jcenter() maven { url 'https://jitpack.io' } } configurations { conversationsFreeCompatImplementation } dependencies { implementation 'androidx.viewpager:viewpager:1.0.0' implementation 'androidx.constraintlayout:constraintlayout:2.0.4' implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" implementation 'org.sufficientlysecure:openpgp-api:10.0' implementation 'com.theartofdev.edmodo:android-image-cropper:2.8.0' implementation 'androidx.appcompat:appcompat:1.3.1' implementation 'androidx.exifinterface:exifinterface:1.3.2' implementation 'androidx.cardview:cardview:1.0.0' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' implementation 'androidx.emoji:emoji:1.1.0' implementation 'com.google.android.material:material:1.4.0' conversationsFreeCompatImplementation 'androidx.emoji:emoji-bundled:1.1.0' implementation 'org.bouncycastle:bcmail-jdk15on:1.64' //zxing stopped supporting Java 7 so we have to stick with 3.3.3 //https://github.com/zxing/zxing/issues/1170 implementation 'com.google.zxing:core:3.4.1' implementation 'de.measite.minidns:minidns-hla:0.2.4' implementation 'me.leolin:ShortcutBadger:1.1.22@aar' implementation 'org.whispersystems:signal-protocol-java:2.8.1' implementation 'com.makeramen:roundedimageview:2.3.0' implementation "com.wefika:flowlayout:0.4.1" implementation 'net.ypresto.androidtranscoder:android-transcoder:0.3.0' implementation 'org.jxmpp:jxmpp-jid:1.0.1' implementation 'org.osmdroid:osmdroid-android:6.1.10' implementation 'org.hsluv:hsluv:0.2' implementation 'org.conscrypt:conscrypt-android:2.5.2' implementation 'me.drakeet.support:toastcompat:1.1.0' implementation "com.leinardi.android:speed-dial:3.2.0" implementation "com.squareup.retrofit2:retrofit:2.9.0" implementation "com.squareup.retrofit2:converter-gson:2.9.0" implementation "com.squareup.okhttp3:okhttp:5.0.0-alpha.2" implementation 'com.squareup.okhttp3:logging-interceptor:5.0.0-alpha.2' implementation 'com.google.guava:guava:30.1.1-android' implementation 'org.webrtc:google-webrtc:1.0.32006' // Lifecycle Helper implementation "androidx.activity:activity-ktx:1.3.0-rc02" implementation "androidx.fragment:fragment-ktx:1.3.6" //Navigation implementation 'androidx.navigation:navigation-fragment-ktx:2.3.5' implementation 'androidx.navigation:navigation-ui-ktx:2.3.5' //CardView implementation "androidx.cardview:cardview:1.0.0" //Country Code Picker implementation 'com.hbb20:ccp:2.5.3' //Firebase implementation 'com.google.firebase:firebase-bom:28.3.0' implementation 'com.google.firebase:firebase-auth-ktx:21.0.1' implementation 'androidx.browser:browser:1.3.0' //OTP view implementation 'com.github.mukeshsolanki:android-otpview-pinview:2.1.2' //Retrofit implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0' //Gson implementation 'com.google.code.gson:gson:2.8.7' //Multidex implementation 'androidx.multidex:multidex:2.0.1' //Round Image implementation 'de.hdodenhof:circleimageview:3.1.0' // Button with image and text implementation 'com.github.Omega-R:OmegaCenterIconButton:0.0.4@aar' //Razor pay implementation 'com.razorpay:checkout:1.6.10' //Mixpanel Tracking implementation 'com.mixpanel.android:mixpanel-android:5.9.1' //Loading screen implementation 'com.wang.avi:library:2.1.3' //Loading implementation 'com.wang.avi:library:2.1.3' //Form implementation 'com.quickbirdstudios:surveykit:1.1.0' } ext { travisBuild = System.getenv("TRAVIS") == "true" preDexEnabled = System.getProperty("pre-dex", "true") abiCodes = ['armeabi-v7a': 1, 'x86': 2, 'x86_64': 3, 'arm64-v8a': 4] } android { compileSdkVersion 31 defaultConfig { minSdkVersion 24 targetSdkVersion 31 versionCode 44 versionName "2.0.4" multiDexEnabled = true archivesBaseName += "-$versionName" applicationId "com.app.app" resValue "string", "applicationId", applicationId def appName = "app" resValue "string", "app_name", appName buildConfigField "String", "APP_NAME", ""$appName"" } splits { abi { universalApk true enable true } } configurations { compile.exclude group: 'org.jetbrains' , module:'annotations' } dataBinding { enabled true } dexOptions { // Skip pre-dexing when running on Travis CI or when disabled via -Dpre-dex=false. preDexLibraries = preDexEnabled && !travisBuild jumboMode true } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } flavorDimensions("mode", "distribution", "emoji") productFlavors { conversations { dimension "mode" } free { dimension "distribution" versionNameSuffix "+f" } compat { dimension "emoji" versionNameSuffix "c" } } sourceSets { conversationsFreeCompat { java { srcDir 'src/freeCompat/java' srcDir 'src/conversationsFree/java' } } } buildTypes { release { shrinkResources true minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' versionNameSuffix "r" } debug { shrinkResources true minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' versionNameSuffix "d" } } if (new File("signing.properties").exists()) { Properties props = new Properties() props.load(new FileInputStream(file("signing.properties"))) signingConfigs { release { storeFile file(props['keystore']) storePassword props['keystore.password'] keyAlias props['keystore.alias'] keyPassword props['keystore.password'] } } buildTypes.release.signingConfig = signingConfigs.release } lintOptions { disable 'MissingTranslation', 'InvalidPackage','AppCompatResource' } subprojects { afterEvaluate { if (getPlugins().hasPlugin('android') || getPlugins().hasPlugin('android-library')) { configure(android.lintOptions) { disable 'AndroidGradlePluginVersion', 'MissingTranslation' } } } } packagingOptions { exclude 'META-INF/BCKEY.DSA' exclude 'META-INF/BCKEY.SF' } android.applicationVariants.all { variant -> variant.outputs.each { output -> def baseAbiVersionCode = project.ext.abiCodes.get(output.getFilter(OutputFile.ABI)) if (baseAbiVersionCode != null) { output.versionCodeOverride = (100 * variant.versionCode) + baseAbiVersionCode } } } }
Advertisement
Answer
I had this issue and one of the libraries I used wasn’t setting it correctly.
Find location
First of all, we need to find the exact location and/or cause for the error,
which can be done with different approaches (see below).
Find by inspecting merged-manifest (approach #1)
You can find it by doing the steps:
Set target SDK to 30 (to silence 31+ errors).
Open application’s manifest (
AndroidManifest.xml
) and click on “Merged Manifest
” tab on bottom of your edit pane:
Which if you configure
build.gradle
like:allprojects { buildDir = "${rootProject.rootDir}/build/${project.name}" }
Something similar should be in a sub-path like:
build/my-app/intermediates/merged_manifest/debug/AndroidManifest.xml
Go to the individual manifest file of all the libraries (You can skip this step if the merged manifest is created and you can just look into the merged manifest)
Search if there’s any entry of type activity, service, receiver, or provider which does not have an
exported
attribute, and for each entry follow below “Fix found entries” section (or see once for how to setexported
attribute).Set target SDK back to 31 (or whatever it was before changing to 30).
Find by console logs (approach #2)
In Git-bash run something like:
./gradlew assembleDebug --stacktrace --info | tee my-logs.txt
Open
my-logs.txt
file (which previous step created, in your preferred text-editor).Now, the exact location is hidden in the logs, hence search in the created
my-logs.txt
file, for these keywords:activity#
service#
receiver#
provider#
Which should find something like:
activity#androidx.test.core.app.InstrumentationActivityInvoker$BootstrapActivity ADDED from [androidx.test:core:1.2.0] C:UsersAdmin.gradlecachestransforms-3709730c74fe4dc9f8fd991eb4d1c2adctransformedjetified-core-1.2.0AndroidManifest.xml:27:9-33:20
- Open
AndroidManifest.xml
file that previous steps did find, search if there’s any entry of typeactivity
,service
,receiver
, orprovider
which does not have anexported
attribute, and see below “Fix found entries” section (for how to set each entriesexported
attribute).
Note that (at time of writting) passing
--stacktrace
alone did not include location info 😉
Fix found entries
If the real (not build-generated) source of found entry is in root-project’s manifest (or somewhere you can alter),
set exported
attribute to corresponding need (which is normally false
) therein directly, like:
<receiver android:name="<name_of_the_entry>" android:exported="false or true" tools:node="merge" />
Note that both
android:exported="..."
andtools:node="merge"
are set above.
But if found entry’s specification is written in the manifest of a third-party library (which’s real-source you can’t alter), override the specification of said library by adding it to our root-project’s manifest, for example like:
<provider android:name="com.squareup.picasso.PicassoProvider" android:exported="false" tools:node="merge" tools:overrideLibrary="com.squareup.picasso.picasso" />
Note that this time
tools:overrideLibrary="..."
is set as well.For more information see Documentation,
and/or Similar issue in a SDK.