Java

androidexported needs to be explicitly specified for activity Apps targeting Android 12 and higher are required to specify

19 September 2026 · 14 min read

androidexported needs to be explicitly specified for activity Apps targeting Android 12 and higher are required to specify

If you’re developing for Android 12 (API level 31) and above, you’ve likely encountered the error message: “android:exported needs to be explicitly specified for ”. This requirement, introduced to enhance app security, mandates that you explicitly declare whether each of your app’s activities can be accessed by other apps. This change significantly impacts how Android apps interact with each other and the system, necessitating a thorough understanding of the implications and proper implementation. Ignoring this can lead to app crashes or unexpected behavior on newer Android versions. Failure to properly configure the android:exported attribute can also create security vulnerabilities, potentially allowing malicious apps to interact with your application in unintended ways. This article will guide you through understanding, implementing, and troubleshooting this critical aspect of Android development.

Understanding the android:exported Attribute

The android:exported attribute within your AndroidManifest.xml file controls whether an activity, service, or broadcast receiver can be invoked by components of other applications. Prior to Android 12, if this attribute wasn’t explicitly set, the system would infer its value based on the presence of intent filters. If an intent filter was present, the component was assumed to be exported (i.e., accessible to other apps). If no intent filter existed, it was assumed to be non-exported. However, this implicit behavior introduced ambiguity and potential security risks.

Android 12 and later versions demand explicit declarations. This means you must clearly state android:exported=“true” if you intend for other apps to start your activity or android:exported=“false” if the activity is only meant for internal use within your own app. This change significantly reduces the attack surface of your application and provides developers with greater control over inter-app communication. According to Google’s official documentation, this requirement is a critical step towards improving the overall security posture of the Android ecosystem. Android 12 Behavior Changes

Consider a scenario where you have an activity that handles custom image editing. If you want other apps to be able to send images to your activity for editing, you would set android:exported=“true” and define an appropriate intent filter. Conversely, if you have an activity that is used solely for internal app settings, you would set android:exported=“false”. Failing to do so will result in a runtime exception on Android 12 and above.

Implementing android:exported in Your Manifest

Implementing the android:exported attribute is straightforward. You simply need to add it to the , , or tag within your AndroidManifest.xml file. The key is to determine whether the component needs to be accessible from outside your application. Carefully analyze each activity, service, and receiver to determine its intended usage.

Here’s how to explicitly set the android:exported attribute:

<activity android:name=".MyActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.SEND" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="image/" /> </intent-filter> </activity> 

In this example, MyActivity is exported because it handles the android.intent.action.SEND intent for images, allowing other apps to share images with it. Remember to add the attribute to every activity, service, and receiver that your app uses, ensuring compliance with Android 12’s requirements and beyond. When auditing your manifest, look for any elements that don’t have the android:exported attribute set.

Troubleshooting Common Issues

One of the most common issues developers face is identifying which activities, services, or receivers require the android:exported attribute. The error message “android:exported needs to be explicitly specified for ” provides a clue, but it doesn’t always pinpoint the exact cause. Carefully review your AndroidManifest.xml file and analyze the intent filters associated with each component.

Another common problem is incorrectly setting android:exported=“true” for activities that should be private. This can expose sensitive data or functionality to other apps. Always prioritize security and carefully consider the implications of exporting each component. Use tools like Lint to help identify potential vulnerabilities and ensure your manifest is properly configured.

If you’re encountering crashes or unexpected behavior after implementing android:exported, double-check that you’ve correctly identified the components that need to be exported and that the intent filters are properly defined. Incorrectly configured intent filters can lead to unexpected behavior and security vulnerabilities. Remember, the goal is to minimize the attack surface of your application while maintaining the necessary functionality.

Best Practices and Recommendations

To effectively manage the android:exported attribute and ensure the security of your application, consider these best practices:

  • Explicitly Declare: Always explicitly declare the android:exported attribute for all activities, services, and receivers.
  • Principle of Least Privilege: Only export components that absolutely need to be accessible from other apps.
  • Regular Audits: Conduct regular audits of your AndroidManifest.xml file to identify potential security vulnerabilities.

Here’s a step-by-step guide to ensure your app is compliant:

  1. Review Manifest: Thoroughly review your AndroidManifest.xml file.
  2. Identify Components: Identify all activities, services, and receivers.
  3. Analyze Intent Filters: Analyze the intent filters associated with each component.
  4. Set android:exported: Explicitly set the android:exported attribute to true or false based on the component’s intended usage.
  5. Test Thoroughly: Test your app thoroughly on Android 12 and above to ensure it functions correctly.

It’s also beneficial to leverage Android’s security features, such as permissions, to further protect your app’s components. Permissions can restrict access to specific activities, services, or receivers, even if they are exported. By combining explicit android:exported declarations with appropriate permissions, you can create a robust security model for your application. Securing your application effectively requires a multi-layered approach.

FAQ: Addressing Common Concerns

What happens if I don't specify android:exported in Android 12?
Your app will likely crash or exhibit unexpected behavior. The system will throw a runtime exception indicating that the attribute must be explicitly declared.
How do I know if my activity needs to be exported?
If your activity needs to be started by other apps (e.g., to handle a specific intent), then it needs to be exported. If it's only used internally within your app, it should not be exported.
Can I use wildcards in the intent filter to match multiple actions?
While wildcards can be used, it's generally recommended to be as specific as possible with your intent filters to minimize the attack surface of your application. [Intents and Intent Filters](https://developer.android.com/guide/components/intents-filters)
Is android:exported only relevant for Android 12 and above?
Yes, the requirement to explicitly specify android:exported was introduced in Android 12. However, it's good practice to include it in your manifest even for older Android versions to avoid potential issues in the future.
*Featured Snippet:* To comply with Android 12's security requirements, you must explicitly declare the android:exported attribute in your AndroidManifest.xml file for all activities, services, and receivers. Set it to true if the component needs to be accessible from other apps, and false if it's only used internally. Failing to do so will result in runtime exceptions and potential security vulnerabilities. This ensures that your app functions correctly and securely on newer Android versions.
  • Security: Prioritize the security of your application.
  • Testing: Thoroughly test your application on Android 12 and above.

Implementing these changes related to android:exported needs to be explicitly specified for requires a bit of work upfront, but the payoff is a more secure and stable application. The Android ecosystem will continue to evolve and it is important to stay up to date on changes. This will make sure that your application is compliant with the latest security best practices. The explicit declaration requirement strengthens the security of the Android platform, providing users with a safer experience.

By understanding the implications of the android:exported attribute and following best practices, you can ensure that your app is not only compliant with Android 12’s requirements but also more secure and reliable. Take the time to review your AndroidManifest.xml file, analyze your components, and explicitly declare the android:exported attribute. This proactive approach will save you from potential headaches down the road and contribute to a more secure Android ecosystem. Need further assistance? Consider exploring Android development resources or seeking expert consultation to optimize your app’s security and performance. Android Security Overview

Question & Answer :
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 } } } } 

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:
    Merged Manifest in Android Studio

    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 set exported 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:\Users\Admin\.gradle\caches\transforms-3\709730c74fe4dc9f8fd991eb4d1c2adc\transformed\jetified-core-1.2.0\AndroidManifest.xml:27:9-33:20 
  • Open AndroidManifest.xml file that previous steps did find, search if there’s any entry of type activity, service, receiver, or provider which does not have an exported attribute, and see below “Fix found entries” section (for how to set each entries exported 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="..." and tools: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.