一. 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都可以拿到合并后的清单文件中, 自己所需要的路径.
其实并没有那么麻烦
网络依赖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合并失败问题.