targetSdkVersion31已配置android:exported仍报Manifest合并错误求助
将应用targetSdkVersion设置为31(对应Android 12),已在AndroidManifest.xml的MainActivity中添加android:exported="true",但编译时仍出现清单合并失败错误,提示面向Android 12及以上的应用需为带intent filter的组件指定明确的android:exported值。
相关配置代码:
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.core_project" xmlns:tools="http://schemas.android.com/tools" > <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <application android:name=".Application" android:label="My App" android:icon="@mipmap/ic_launcher" android:usesCleartextTraffic="true" tools:replace="allowBackup" android:allowBackup="false" android:requestLegacyExternalStorage="true"> <meta-data android:name="io.flutter.embedding.android.SplashScreenDrawable" android:resource="@drawable/launch_background"/> <meta-data android:name="com.google.firebase.messaging.default_notification_icon" android:resource="@drawable/ic_default_tray" /> <meta-data android:name="com.google.firebase.messaging.default_notification_color" android:resource="@color/colorIconNotificationTray" /> <meta-data android:name="flutterEmbedding" android:value="2" /> <provider android:name="vn.hunghd.flutterdownloader.DownloadedFileProvider" android:authorities="${applicationId}.flutter_downloader.provider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/provider_paths"/> </provider> <!-- Begin FlutterDownloader customization --> <!-- disable default Initializer --> <provider android:name="androidx.startup.InitializationProvider" android:authorities="${applicationId}.androidx-startup" android:exported="false" tools:node="merge"> <meta-data android:name="androidx.work.WorkManagerInitializer" android:value="androidx.startup" tools:node="remove" /> </provider> <!-- declare customized Initializer --> <provider android:name="vn.hunghd.flutterdownloader.FlutterDownloaderInitializer" android:authorities="${applicationId}.flutter-downloader-init" android:exported="false"> <meta-data android:name="vn.hunghd.flutterdownloader.MAX_CONCURRENT_TASKS" android:value="5" /> </provider> <activity android:screenOrientation="portrait" android:name=".MainActivity" android:launchMode="singleTop" android:theme="@style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize" android:exported="true" > <meta-data android:name="com.google.firebase.messaging.default_notification_channel_id" android:value="channel id"/> <meta-data android:name="io.flutter.app.android.SplashScreenUntilFirstFrame" android:value="true" /> <meta-data android:name="com.google.firebase.ml.vision.DEPENDENCIES" android:value="barcode" /> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> <intent-filter> <action android:name="FLUTTER_NOTIFICATION_CLICK" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> <!-- Branch URI Scheme --> <intent-filter> <data android:scheme="mydestiny" android:host="open" /> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> </intent-filter> <!-- Branch App Links --> <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" android:host="mydestiny.app.link" /> <!-- example-alternate domain is required for App Links when the Journeys/Web SDK and Deepviews are used inside your website. --> <data android:scheme="https" android:host="mydestiny-alternate.app.link" /> </intent-filter> </activity> <!-- Branch init --> <meta-data android:name="io.branch.sdk.BranchKey" android:value="key_live_XXXXXXXXXXXXXXXXXXXXXXXXXX" /> <meta-data android:name="io.branch.sdk.BranchKey.test" android:value="secret_live_XXXXXXXXXXXXXXXXXXXXXXXXXX" /> <meta-data android:name="io.branch.sdk.TestMode" android:value="false" /> </application> </manifest>
build.gradle 配置
defaultConfig { applicationId "com.example.core_project" minSdkVersion 23 targetSdkVersion 31 versionCode 1 versionName "1.0." testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" }
错误核心是:所有带有<intent-filter>的组件(Activity、Service、Receiver、Provider)都必须显式指定android:exported属性,不仅限于你自己编写的MainActivity,第三方依赖库中的组件也需要满足要求。
步骤1:定位具体缺失android:exported的组件
查看Android Studio Build窗口的完整错误日志,日志会明确指出是哪个组件(如某Service、Receiver)未指定android:exported,这是最关键的一步,不要盲目猜测。
步骤2:针对性修复
根据日志提示的组件,有两种修复方式:
方式A:升级依赖库到支持Android 12的版本
大部分主流第三方库(如Firebase、Branch、FlutterDownloader)已更新版本,在内部清单中添加了android:exported属性。例如:
- 升级Firebase BOM到最新版本
- 升级FlutterDownloader到2.0+版本
- 升级Branch SDK到5.0+版本
方式B:在自己的清单中显式声明组件并添加android:exported
若暂时无法升级依赖库,就在AndroidManifest.xml中重新声明该组件,指定android:exported属性(需要被外部调用则设为true,仅内部使用则设为false),并用tools:node="merge"处理合并冲突。
以下是几个常见出问题的组件示例:
示例1:FirebaseMessagingService
<service android:name="com.google.firebase.messaging.FirebaseMessagingService" android:exported="false"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service>
示例2:BranchDeepLinkingReceiver
<receiver android:name="io.branch.referral.BranchDeepLinkingReceiver" android:exported="true"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> <action android:name="android.intent.action.ACTION_PACKAGE_ADDED" /> <action android:name="android.intent.action.ACTION_PACKAGE_CHANGED" /> <action android:name="android.intent.action.ACTION_PACKAGE_INSTALL" /> <action android:name="android.intent.action.ACTION_PACKAGE_REPLACED" /> <action android:name="android.intent.action.ACTION_PACKAGE_REMOVED" /> </intent-filter> </receiver>
步骤3:验证修复
添加完成后重新编译,若仍有错误,重复步骤1和2,直到所有带<intent-filter>的组件都指定了android:exported属性。
内容的提问来源于stack exchange,提问作者SK-

