Android 12 android:exported Property Requirement
Problem
Starting with Android 12 (API level 31), Google requires all app components with intent filters to explicitly declare the android:exported attribute. This security measure prevents unauthorized apps from accessing your app's components without proper configuration.
The error occurs when you upload an APK or Android App Bundle that contains activities, services, broadcast receivers, or activity aliases with intent filters but without the android:exported property explicitly set to either true or false.
Solution
1. Basic Fix: Add android:exported to Your Components
For each component in your AndroidManifest.xml that contains an <intent-filter>, add the android:exported attribute:
<!-- For activities -->
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- For services -->
<service
android:name=".MyService"
android:exported="false">
<intent-filter>
<action android:name="com.example.app.ACTION_START" />
</intent-filter>
</service>
<!-- For broadcast receivers -->
<receiver
android:name=".MyReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>TIP
- Set
android:exported="true"for components that should be accessible from other apps - Set
android:exported="false"for components that should only be used within your app - Components with the
LAUNCHERcategory should typically haveexported="true"
2. Identify Problematic Components Using Merged Manifest
Many issues come from third-party libraries that haven't been updated for Android 12 compliance. Use Android Studio's Merged Manifest view to identify all components:
- Open your project in Android Studio
- Navigate to
app/src/main/AndroidManifest.xml - Click the "Merged Manifest" tab at the bottom
- Look for components with intent filters missing the
exportedattribute
WARNING
If you don't see the Merged Manifest tab, ensure your build.gradle has compileSdkVersion and targetSdkVersion set to at least 30, then sync your project.
3. Fixing Third-Party Library Components
When you identify problematic components from libraries, override them in your main manifest:
<!-- Example for Razorpay components -->
<activity
android:name="com.razorpay.CheckoutActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:theme="@style/CheckoutTheme"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<data
android:host="rzp.io"
android:scheme="io.rzp" />
</intent-filter>
</activity>
<receiver
android:name="com.razorpay.RzpTokenReceiver"
android:exported="true"
android:permission="android.permission.INTERNET">
<intent-filter>
<action android:name="rzp.device_token.share" />
</intent-filter>
</receiver>4. Common Library Fixes
For specific libraries, here are common fixes:
Flutter Local Notifications:
<receiver android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationBootReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED"/>
</intent-filter>
</receiver>Firebase Messaging:
<service
android:name="com.google.firebase.messaging.FirebaseMessagingService"
android:exported="true">
<intent-filter android:priority="-500">
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>5. Alternative: Manual Merged Manifest Inspection
If you can't use Android Studio's Merged Manifest view:
- Build your project
- Locate the merged manifest file at:
app/build/intermediates/merged_manifests/release/AndroidManifest.xml - Search for components with
<intent-filter>but withoutandroid:exported - Copy these components to your main manifest and add the
exportedattribute
6. Framework-Specific Solutions
React Native: Update all third-party libraries to their latest versions, as many have been updated for Android 12 compliance.
Flutter: Ensure you're using updated versions of plugins, particularly:
flutter_local_notifications: ^15.1.1or higher- Other plugins that use background services or receivers
Unity:
- Export your project as an Android project
- Open in Android Studio to use the Merged Manifest tool
- Copy problematic components to
Assets/Plugin/Android/AndroidManifest.xml
Ionic/Cordova: Add to your config.xml:
<platform name="android">
<edit-config file="app/src/main/AndroidManifest.xml" mode="merge"
target="/manifest/application/activity"
xmlns:android="http://schemas.android.com/apk/res/android">
<activity android:exported="true" />
</edit-config>
</platform>Best Practices
- Always explicitly declare
android:exportedfor components with intent filters - Keep libraries updated to avoid manual fixes
- Use the minimum necessary exposure - don't set
exported="true"unless required - Test thoroughly after making changes to ensure functionality isn't broken
DANGER
Avoid downgrading your targetSdkVersion to bypass this requirement, as this is a temporary fix that will eventually stop working and may cause other compatibility issues.
By following these steps, you should be able to resolve the Android 12 exported property requirement and successfully publish your app to the Google Play Store.