阅读 221

自动更新在安卓7.0机型遇到的坑

应用内更新相信对很多人来说是最基本也是最常见的功能,本来一直好好的更新功能,突然测试跟我说,7.0上的机型发送了崩溃,当时的第一反应是,不应该啊,这个功能都用了好久了,怎么之前一直都没听到过说有什么问题啊。虽然不是很相信,但还是第一时间看了下,我了个**,还真一直崩溃,这彻底击碎了我一开始以为的是偶发事件了。 在这节骨眼上,马上要发版了,结果,现在出这幺蛾子,没办法,兵来将挡水来土掩,然后开始解决问题。 问题的描述是这样的:

android.os.FileUriExposedException:exposed beyond app through Intent.getData()

找了下万能的谷歌大兄弟,是7.0的权限机制搞的鬼,这兼容性真心有时候搞得人头大。既然找出了问题,那就按照方案解决呗,心里觉得这个也简单。解决方案如下:

1、在AndroidManifest.xml中添加代码

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

是的,这也是网上搜到最多的解决方案。(但有可能你会遇到坑,后面再说)

2、res添加下添加xml文件夹和provider_paths.xml 文件

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path
        name="external_files"
        path="." />
    <root-path
        name="root_path"
        path="." />
</paths>
复制代码

这里面的具体写法,可以参考谷歌文档,传送门(请自备梯子),不多说。

3、调用的安装代码需要修改下

        File apkfile = new File(saveFileName);
        if (!apkfile.exists()) {
            return;
        }
        Intent intent = new Intent(Intent.ACTION_VIEW);
        //判断是否是AndroidN以及更高的版本
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
            Uri contentUri = FileProvider.getUriForFile(mContext, BuildConfig.APPLICATION_ID + ".versionProvider", apkfile);
            intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
        } else {
            intent.setDataAndType(Uri.fromFile(apkfile), "application/vnd.android.package-archive");
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        }
        mContext.startActivity(intent);
复制代码

一般的情况,到这里应该就结束了,但我这次,把这些都弄好了之后,正准备来验收成果的时候,居然编译报错了,报错了,报错了,你没看错,编译报了

Manifest merger failed with multiple errors, see logs

看提示,应该是资源冲突了,但是 tools:replace="android:label,icon,theme,allowBackup" 我都设置了,另外我也检查了我的 AndroidManifest.xml 里也没有其他的 FileProvider,连第三方的库我也检查了没有,然后把这段代码注释编译一点问题没有,谷歌了大半个地球回来的解决方案没一个有用的,真心日**,就在我的好耐心快被耗光的时候,突然灵机一动,我不用系统提供的这个,自己包装下,修改如下:

public class MyFileProvider extends FileProvider {
}
复制代码

你没看错,的确就这么简单,然后把 AndroidManifest.xml 里的路径也做相应的修改,最后也记得将

Uri contentUri = FileProvider.getUriForFile(mContext, BuildConfig.APPLICATION_ID + ".versionProvider", apkfile);

替换为:

Uri contentUri = MyFileProvider.getUriForFile(mContext, BuildConfig.APPLICATION_ID + ".versionProvider", apkfile);

再次进行激动的编译中。。。

OK,大功告成,没有报错,马上运行下,颤抖的按下了更新,奇迹发生了,顺利安装完成了,那么这次的bug修复就完成了。希望能帮助到有需要的人~