一、问题背景
在应用中同时集成来 个推和百度 两个三方消息推送平台,在开发调试阶段一直是编译的debug版本,没有出现问题。
后面在应用阶段编译release 版本突然出现如下报错:
AndroidManifest.xml: Error: Permission name BaseWebviewApp is not unique (appears in both baidu.push.permission.WRITE_PUSHINFOPROVIDER.com.org.BaseWebviewApp and getui.permission.GetuiService.com.org.BaseWebviewApp) [UniquePermission]
二、问题分析
刚看到这个报错有点莫名其妙,两个权限名字前面一节那么长完全不同,为何会报重名? 而且报错的地方显示的是lint 工具问题,所以我就想是不是可以将lint 检查直接关闭,在网上搜寻了一番方法,屡试屡败。 于是才开始继续研究自定义权限的用法。
<permission
android:name="baidu.push.permission.WRITE_PUSHINFOPROVIDER.${applicationId}"
android:protectionLevel="signature" />
<permission
android:name="getui.permission.GetuiService.${applicationId}"
android:protectionLevel="normal" />
<permission> 用来定义权限
<use-permission> 用来使用权限
具体参照如下文章说明:
https://blog.csdn.net/lclfeng/article/details/106313676
其中提到的最后一点很重要:
注意
这也是我们项目中出现问题的原因:
系统不允许多个软件包声明同名权限,除非所有软件包均使用同一证书进行签名。如果软件包声明了某个权限,则系统不会允许用户安装其他具有相同权限名称的软件包,除非这些软件包使用与第一个软件包相同的证书进行签名。在为自定义权限命名时,为了避免命名冲突,我们建议采用反向域名方式,例如 com.example.myapp.ENGAGE_HYPERSPACE。
于是我将AndroidManifest.xml 中的个推和百度分别需要使用包名自定义的权限以及使用权限的地方的name都改为将包名放在前面,后面为各自厂商定义的字符串:
<permission
android:name="${applicationId}.baidu.push.permission.WRITE_PUSHINFOPROVIDER"
android:protectionLevel="signature" />
<permission
android:name="${applicationId}.getui.permission.GetuiService"
android:protectionLevel="normal" />
果然如此修改之后,release版本编译正常,测试功能也无影响
后来才发现在三方推送平台中做的最好的极光推送,其也有自定义权限,声明方式就是将包名放在前面的,看来是有考虑这个问题:
<permission
android:name="${applicationId}.permission.JPUSH_MESSAGE"
android:protectionLevel="signature" />
好的平台对于开发者来说也是比较友好的,从细节可以看出来。
另外,最终发现这个错误确实是lint 检测,之前配置不生效是因为没有配置正确,如果需要忽略可以在gradle 中做如下配置:
lintOptions {
checkReleaseBuilds false
abortOnError false
}