bugly自动升级在android7.0系统上重复下载 bugly与takephoto适配7.0冲突问题

该博客解决bugly自动升级无法适配7.0系统.  

bug现象: 在7.0及以上系统上,bugly更新app后,不停重复下载, 无法进入安装界面. 同时, 在解决bugly该bug时, 与takephoto适配7.0的代码发生冲突.


一. bugly升级库无法适配7.0系统原因

因为7.0系统增强了私有文件访问权限, 下载新版本的APP后, 可能没有权限拿到下载的APP的路径, 所以会重复下载


二. 解决bugly适配7.0系统

根据多方的资料, 我们在清单文件中配置如下代码即可. 

<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="${applicationId}.fileProvider"
    android:grantUriPermissions="true"
    android:exported="false">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/provider_paths" />
provider>
.......
application>



创建 res/xml/provider_paths.xml


xml version="1.0" encoding="utf-8"?>
<resources>
    <paths>
        <external-path
            name="files_root"
            path="Android/data/com/pgyersdk" />
        <external-path
            name="external_storage_root"
            path="." />
    paths>
resources>

此时已经解决了问题, 可以解决bugly问题.

但是如果您的项目中集成了takephoto, 此时编译时会报错的. 报错信息为合并xml文件失败, 指向于Provider. 

这是因为takephoto的清单文件中也使用了一个android:name="android.support.v4.content.FileProvider"; 

所以会报合并失败, 在一些博客中, 还有github takephoto的Issues中提出的解决办法.

解决方法如下:

2.1  导入离线库takehpoto, 然后将原码修改.

修改内容如下:

修改com.jph.takephoto.uitl.TConstant的方法getFileProviderName。
public final static String getFileProviderName(Context context){
return context.getPackageName()+".fileprovider";
}
改为:
public final static String getFileProviderName(Context context){
return context.getPackageName()+".fileProvider";
}

2.2 将清单文件的Provider中添加替换规则, 代码如下:  达到的效果是替换掉所有name: android.support.v4.content.FileProvider中的属性

<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="${applicationId}.fileProvider"
    android:grantUriPermissions="true"
    tools:replace="name,authorities,exported,grantUriPermissions"
    android:exported="false">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
       tools:replace="name,resource" 
android:resource= "@xml/file_paths" /> provider >

2.3 在APP的res/xml/中创建file_paths.xml文件

将bugly  和takehpoto所需要访问的目录路径添加进去

文件内容如下:

xml version="1.0" encoding="utf-8"?>
<resources>
    <paths>
        <external-path
            name="files_root"
            path="Android/data/com/pgyersdk" />
        <external-path
            name="external_storage_root"
            path="." />
	<root-path path="" name="camera_photos" />
paths > resources >

这样就完成了. 

这种解决方案的思路是: bugly和takephoto都要调用Provider 的authorities属性

但是bugly调用的authorities="${applicationId}.fileProvider", 

而takephoto框架中调用的是authorities="${applicationId}.fileprovider"

其实就是一个大写一个小写, 怎么说了, takephoto的作者没有采用驼峰命名. 从takyphoto框加的原码和清单文件配置中, 可以看到, 它所调用的就是小写的.fileprovider这个属性值

我们在APP的清单文件中创建了一个和takephoto中所需xml一样文件名的文件-----file_paths.xml; 并将bugly takephoto所需要文件路径全部复制进去

然后在清单文件中创建name值一样的Provider标签. 并将authorities="${applicationId}.fileProvider", 

因为修改takephoto原码, 就可以让takephoto访问拿到APP层fileProvider, 而不是fileprovider

这样bugly 和takephoto都可以拿到合并后的清单文件中, 自己所需要的路径.


三 .  终结解决方案:  自定义provider

其实并没有那么麻烦

网络依赖takephoto库, 不用导离线库

3.1 在APP层自定义一个provider.

创建BuglyFileProvider.java

/**
 * Created by liuyu on 2017/5/22.
 */
//解决bugly适配7.0系统
public class BuglyFileProvider extends android.support.v4.content.FileProvider {
}

3.2 在res/ xml/ file_paths_bugly.xml 

xml version="1.0" encoding="utf-8"?>
<resources>
    <paths>
        <external-path
            name="files_root"
            path="Android/data/com/pgyersdk" />
        <external-path
            name="external_storage_root"
            path="." />
    paths>
resources>


3.3 在清单文件中配置如下


<provider
    android:name=".utils.BuglyFileProvider"
    android:authorities="${applicationId}.fileProvider"
    android:exported="false"
    android:grantUriPermissions="true"
    tools:replace="name,authorities,exported,grantUriPermissions">

    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths_bugly"
        tools:replace="name,resource" />
provider>

!大功告成

上面所有创建的文件名随意, 不影响结果

思路: 创建一个自定义的Provide, 继承v4包的Provider; 然后将authorities的值设置为 android:authorities="${applicationId}.fileProvider"


然后将resource中的xml添加bugly所需的路径

而takephoto还是使用网络依赖, 使用它自己清单文件中配置的那个file_path.xml中路径.

我们从合并后的清单文件中可以查到自定义的provider和takephoto库中的provider

建议: takephoto bugly两个框架都使用自定义的Provide, 以免发生xml合并失败问题.



你可能感兴趣的:(andriod)