升级targetSdkVersion至31,如何自动为ShareChooserPendingIntent添加android:exported属性
问题描述
升级targetSdkVersion到31时,触发清单合并错误:
Error: android:exported needs to be explicitly specified for . Apps targeting Android 12 and higher are required to specify an explicit value for
android:exportedwhen the corresponding component has an intent filter defined.
问题出在自动生成的capacitor-cordova-android-plugins/src/main/AndroidManifest.xml文件中,接收器nl.xservices.plugins.ShareChooserPendingIntent未声明android:exported属性,代码如下:
<receiver android:name="nl.xservices.plugins.ShareChooserPendingIntent" android:enabled="true"> <intent-filter> <action android:name="android.intent.action.SEND"/> </intent-filter> </receiver>
手动添加android:exported="false"后可正常构建,但该文件会在同步/构建时被重新生成,需要无需手动编辑的持久化解决方案。
解决方案
方法1:主清单文件合并覆盖(推荐)
在项目的主AndroidManifest.xml中,通过清单合并规则为目标接收器指定android:exported属性,无需修改自动生成的插件清单。
在主清单的<application>标签内添加以下代码:
<receiver android:name="nl.xservices.plugins.ShareChooserPendingIntent" android:exported="false" xmlns:tools="http://schemas.android.com/tools" tools:node="merge" />
tools:node="merge":会将主清单中的属性合并到插件清单的对应组件上,保留原组件已有的属性(比如android:enabled="true")。- 若需要强制替换属性,可改用
tools:node="replace",但优先推荐merge以避免覆盖原有配置。
方法2:Cordova Hook脚本自动修改
编写构建hook脚本,在构建流程中自动修改生成的插件清单文件:
- 在项目根目录创建
hooks/after_prepare/add_exported_attribute.js文件,内容如下:
const fs = require('fs'); const path = require('path'); module.exports = function(context) { const manifestPath = path.join(context.opts.projectRoot, 'capacitor-cordova-android-plugins/src/main/AndroidManifest.xml'); if (fs.existsSync(manifestPath)) { let content = fs.readFileSync(manifestPath, 'utf8'); const updatedContent = content.replace( /<receiver android:name="nl.xservices.plugins.ShareChooserPendingIntent" android:enabled="true">/, '<receiver android:name="nl.xservices.plugins.ShareChooserPendingIntent" android:enabled="true" android:exported="false">' ); fs.writeFileSync(manifestPath, updatedContent, 'utf8'); console.log('Successfully added android:exported="false" to ShareChooserPendingIntent receiver'); } };
- 在
config.xml中注册该hook:
<platform name="android"> <hook type="after_prepare" src="hooks/after_prepare/add_exported_attribute.js" /> </platform>
每次构建前,脚本会自动检查并修改目标清单文件,添加所需属性。
方法3:更新适配Android 12的插件版本
该接收器来自cordova-plugin-x-socialsharing插件,检查是否有适配Android 12的新版本,直接更新插件即可解决:
cordova plugin update cordova-plugin-x-socialsharing
新版本插件通常已内置android:exported属性的正确配置,无需额外修改。
内容的提问来源于stack exchange,提问作者Souleste

