Android Studio构建项目遇Manifest合并错误:C2D_MESSAGE权限问题求解
这个问题我碰到过好多次,本质上是Firebase Cloud Messaging(或者旧版GCM)的C2D_MESSAGE权限要么没和你的应用包名正确关联,要么是多个依赖库/模块的Manifest文件重复定义了这个权限,导致合并时冲突。下面按优先级给你几个靠谱的解决办法:
方法1:手动补全完整包名
打开你的AndroidManifest.xml,找到这两行权限声明(如果有的话):
<permission android:name=".permission.C2D_MESSAGE" android:protectionLevel="signature" /> <uses-permission android:name=".permission.C2D_MESSAGE" />
把里面的.permission.C2D_MESSAGE替换成你完整的应用包名,比如你的包名是com.yourcompany.yourapp,就改成:
<permission android:name="com.yourcompany.yourapp.permission.C2D_MESSAGE" android:protectionLevel="signature" /> <uses-permission android:name="com.yourcompany.yourapp.permission.C2D_MESSAGE" />
直接用完整包名绑定权限,就不会出现模糊匹配的问题了。
方法2:用Manifest占位符自动填充(推荐)
如果你用的是Android Gradle Plugin 3.0及以上版本,更省心的方式是用占位符让Gradle自动帮你替换包名:
- 打开模块级的
build.gradle,在android->defaultConfig里添加:
manifestPlaceholders = [ appPackage: "${applicationId}" ]
- 回到
AndroidManifest.xml,把权限声明改成:
<permission android:name="${appPackage}.permission.C2D_MESSAGE" android:protectionLevel="signature" /> <uses-permission android:name="${appPackage}.permission.C2D_MESSAGE" />
这样不管你后续怎么修改包名,Gradle都会自动同步替换,再也不用手动改Manifest了。
方法3:强制覆盖冲突的权限声明
如果是因为多个第三方依赖库都定义了这个权限导致合并冲突,那就直接在你的Manifest里强制覆盖:
首先要在Manifest的根标签里引入tools命名空间:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="com.yourcompany.yourapp">
然后在权限声明里加上tools:replace="android:name":
<permission android:name="com.yourcompany.yourapp.permission.C2D_MESSAGE" android:protectionLevel="signature" tools:replace="android:name" /> <uses-permission android:name="com.yourcompany.yourapp.permission.C2D_MESSAGE" tools:replace="android:name" />
这样Gradle合并Manifest的时候,就会优先使用你定义的权限版本,忽略依赖库的冲突声明。
方法4:检查FCM依赖配置
如果上面的方法都没用,可能是你的FCM依赖配置有问题:
- 确保项目级
build.gradle里的Google服务插件是最新稳定版:
dependencies { classpath 'com.google.gms:google-services:4.3.15' // 可以换成最新版 }
- 模块级
build.gradle末尾一定要加上Google服务插件的引用:
apply plugin: 'com.google.gms.google-services'
旧版本的依赖经常会出现Manifest生成异常,更新到最新版往往能解决这类奇怪的问题。
一般来说,方法1或方法2就能解决绝大多数情况,要是还不行就试试方法3和4。
内容的提问来源于stack exchange,提问作者MD. EMRAN HOSSAIN

