欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  技术分享

android.os.FileUriExposedException_Android 7.0适配更新

程序员文章站 2022-02-22 08:16:24
...

最近在集成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直接是应用的包名