android.os.FileUriExposedException_Android 7.0适配更新
2017-09-11 14:14:39  By: dwtedx

最近在集成AutoInstaller实现应用程序静默更新的时候出现了这样一个报错、开始因为我刚刚升级了MiUI9、以为是MIUI9的问题、可是后来越来越觉得不对劲、最好才发现是Android 7.0的适配android.os.FileUriExposedException的问题、Android 7.0以后提高了私有文件的安全性、其私有目录将会限制访问、若要在应用间共享文件、您需要发送一项 content:// URI,并授予 URI 临时访问权限

android.os.FileUriExposedException: file:///storage/emulated/0/Download/***.apk exposed beyond app through Intent.getData()


解决方法

1、AndroidManifest.xml中application节点下面添加如下代码、注:android:authorities=”你应用程序包名.fileProvider”

<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="top.wuhaojie.installerlibrary.fileProvider"
    android:grantUriPermissions="true"
    android:exported="false">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths" />
</provider>


2、在app—>res下新建一个xml文件夹、文件夹中新建file_paths.xml文件、写入代码如下、注: < external-path path=”Android/data/你应用程序包名/” name=”files_root” />
<paths>
    <external-path path="Android/data/top.wuhaojie.installerlibrary/" name="files_root" />
    <external-path path="." name="external_storage_root" />
</paths>


3、在报错代码的位置做如下修改(installApk方法)

private void installApk() {
    //下载完成,点击安装
    Uri uri = Uri.fromFile(FileUtil.updateFile);
    Intent intent = new Intent(Intent.ACTION_VIEW);
    //判断是否是AndroidN以及更高的版本
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        Uri contentUri = FileProvider.getUriForFile(UpdateService.this, BuildConfig.APPLICATION_ID   ".fileProvider", FileUtil.updateFile);
        intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
    } else {
        intent.setDataAndType(uri, "application/vnd.android.package-archive");
        //加这个属性是因为使用Context的startActivity方法的话,就需要开启一个新的task
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    }
    UpdateService.this.startActivity(intent);
}


总结

1、首先我们对Android N及以上做判断

2、然后添加flags、表明我们要被授予什么样的临时权限

3、以前我们直接 Uri.fromFile(apkFile)构建出一个Uri,现在我们使用FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID ".fileProvider", apkFile);

4、BuildConfig.APPLICATION_ID直接是应用的包名

若资源对你有帮助、浏览后有很大收获、不妨小额打赏我一下、你的鼓励是维持我不断写博客最大动力

想获取DD博客最新代码、你可以扫描下方的二维码、关注DD博客微信公众号(ddblogs)

或者你也可以关注我的新浪微博、了解DD博客的最新动态:DD博客官方微博(dwtedx的微博)

如对资源有任何疑问或觉得仍然有很大的改善空间、可以对该博文进行评论、希望不吝赐教

为保证及时回复、可以使用博客留言板给我留言: DD博客留言板(dwtedx的留言板)

感谢你的访问、祝你生活愉快、工作顺心、欢迎常来逛逛


快速评论


技术评论

  • 该技术还没有评论、赶快抢沙发吧...
DD记账
top
+