现象
安装应用的时候会提示安装失败,提示信息是INSTALL FAILED CONFLICTING PROVIDER,如下图所示:
究其原因
根据英文我们可以直观的知道因为provider的问题,在Android中provider的authority
要求必须是唯一的,比如你在定义一个provider
时需要为它指定一个唯一的authority
。如果你在安装一个带有provider
的应用时,系统会检查当前已安装应用的authority
是否和你要安装应用的authority
相同,如果相同则会弹出上述警告,并且安装失败。
这种问题多出现在接入第三方SDK、多个项目共用一个Module或Library,并且用到了provider。
解决方案
1. 简单粗暴
修改provider的
authority
,确保authority的命名唯一。这样以硬编码的形式进行修改,会很麻烦,每次新建项目添加已有的Module或Library都要修改他们包含的provider的authority。不建议这样使用硬编码的形式进行解决这个问题。这里就不过多陈述了。2.以柔克刚
在定义provider的时候,authority使用软编码。这样即使多个项目引用同一个Module或Library,其定义的provider的名字都不用进行修改了。
举例:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths"/>
</provider>
上述代码中通过${applicationId}.fileprovider的形式来指定provider的authorities,所以该provider的authorities会根据applicationId的不同而不同,从而避免了authorities的冲突问题。
接着大家心中会有疑问?那authorities的URI不能在代码里声明常量了,那怎么获取呢?只要肯想,还是有办法的。
直接上代码:
Java
public class ProviderUtils {
public static String getAuthority(Context context, String providerClassName) {
try {
ComponentName componentName = new ComponentName(context.getApplicationContext(), providerClassName);
ProviderInfo providerInfo = context.getPackageManager().getProviderInfo(componentName, 0);
return providerInfo.authority;
} catch (PackageManager.NameNotFoundException e) {
return providerClassName;
}
}
}
Kotlin
@JvmStatic
fun getAuthority(context: Context?, providerClassName: String): String {
return context?.let {
try {
val componentName = ComponentName(context.applicationContext, providerClassName)
val providerInfo = context.packageManager.getProviderInfo(componentName, 0)
providerInfo.authority
} catch (e: Exception) {
providerClassName
}
} ?: ""
}
使用的时候代码展示如下:
FileProvider.getUriForFile(pContext, ProviderUtil.getAuthority(pContext, FileProvider::class.java.name), pFile)
OK,这样就一劳永逸了,再创建新的项目直接使用共用的Module或Library,就不用担心Provider冲突的问题了。
我在这里强烈建议大家使用以柔克刚的方案。
推荐阅读: