INSTALL_FAILED_CONFLICTING_PROVIDER

前言

  首先,我们项目分为三个环境,开发环境,测试环境,生产环境。测试人员是在测试环境进行测试,而运营那边使用的试生产环境的app,然后测试同学说,运营那边在使用的时候如果遇到什么问题,他需要下载一个生产环境的包去上面进行验证,但是这样就会导致本地的测试环境的包被覆盖掉了,希望能够在手机上装两个相同的app。于是乎,为了满足测试小姐姐的这个需求,在修改的过程中就有了下面的问题。

产生原因

  平常我们在做app开发过程中,可能自己编写ContentProvider的情况比较少,所以可能碰到这种情况的比较少,但是android7.0的严格模式,外部app无法访问本app的私有目录,我们得通过FileProvider进行目录共享,而FileProvider就是继承ContentProvider的。我们需要在AndroidManifest.xml文件中配置provider节点。

1
2
3
4
5
6
7
<provider android:authorities="com.fxyan.demo.fileProvider"
android:name="android.support.v4.content.FileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data android:name="FILE_PROVIDER_PATHS"
android:resource="@xml/file_provider_paths"/>
</provider>

  而每个provider是需要指定一个authorities的,这个值在Android系统中必须是唯一的。为了满足测试小姐姐的需求,我在build.gradle文件中配置了多个buildType,对每个buildType增加了一个applicationIdSuffix,如下所示。

1
2
3
4
5
6
7
debug {
applicationIdSuffix ".debug"
//...
}
release {
//...
}

  比如,我们项目的applicationId为”com.fxyan.deom”,那么你在打debug包的时候,apk的applicationId就是”com.fxyan.demo.debug”,这样就保证debug包和release在手机上能够同时存在。
  但是结果并不如意,我在装两个包的时候,AS弹出了如下的对话框。
001
  这就是我前面说到的,因为我们配置的provider的authorities是一个硬编码的字符串,我们应该让其跟着applicationId来变动。

1
2
3
4
5
6
7
<provider android:authorities=${applicationId}.fileProvider"
android:name="android.support.v4.content.FileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data android:name="FILE_PROVIDER_PATHS"
android:resource="@xml/file_provider_paths"/>
</provider>

  像上面这样修改之后,再次安装就可以了。

本文标题:INSTALL_FAILED_CONFLICTING_PROVIDER

文章作者:严方雄

发布时间:2018-11-20

最后更新:2018-11-20

原始链接:http://yanfangxiong.com/2018/11/20/INSTALL-FAILED-CONFLICTING-PROVIDER/

0%