android7.0后file访问,Android 7.0 通过FileProvider共享文件

一.概述

Android 7.0后,提供了很多新特性,其中最主要的是禁止了通过file://URI直接在文件操作共享文件(该操作会触发FileUriExposedException),而是通过content://URI来实现共享。

FileRrovider是ContentProvider的子类,用于不同应用间的文件共享。

二 使用

1.在Mainfest文件中声明provider。

2.编写资源文件provider_paths。

在paths节点内部支持以下几个子节点,分别为:

代表设备的根目录new File("/");

代表context.getFilesDir()

代表context.getCacheDir()

代表Environment.getExternalStorageDirectory()

代表context.getExternalFilesDirs()

代表getExternalCacheDirs()

path代表目录下的子目录,如:

/>

代表context.getChcheDir()/path目录,如果path为空,代表直接使用该根目录。

既然要使用content://URI替代file://URI,那么我们需要一个虚拟路径对真实文件路径进行映射。通过编写xml文件,其中path路径确定了可访问的文件目录,name属性映射了真实文件路径。

3.使用fileProvider API 安装APK

我们一般编写安装APK操作时,是这么写的。

private voidinstallAPK() {

File file= new File(Environment.getExternalStorageDirectory(),"test.apk");

Intent intent= newIntent(Intent.ACTION_VIEW);

intent.setDataAndType(Uri.fromFile(file),"application/vnd.android.package-archive");

startActivity(intent);

}

拿着在7.0上的手机跑一下,果不其然会报android.os.FileUriExposedException。

简单修改下URI的获取方式。

private voidinstallAPK() {

File file= new File(Environment.getExternalStorageDirectory(),"test.apk");

Intent intent= newIntent(Intent.ACTION_VIEW);

Uri fileUri= null;if(Build.VERSION.SDK_INT >= 24){//输出 content://com.example.fanggao.fgtextdemo/external/test.apk

fileUri = FileProvider.getUriForFile(this,BuildConfig.APPLICATION_ID+".fileProvider",file);

}else{

fileUri=Uri.fromFile(file);

}

intent.setDataAndType(fileUri,"application/vnd.android.package-archive");

intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION|Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

startActivity(intent);

}

这样就可以正常运行了。注意,我们还需要加上权限,否则会报Permission Denial异常。

那么问题来了,当我们直接使用fileProvider时,在5.0以下的手机也会报Permission Denial异常,是不是也可以使用addFlags()方法添加权限呢?

答案是不行的,但addFlags只是使用与setData,setDataandType以及setClipData,而且该方法在5.0以下是无效的,需要使用grantUrlPermission()方法,获取所有符合授权的应用,全部授权。

三 小结

7.0后使用fileProvider来实现文件共享,主要目的是隐藏真实的文件目录,因为fileProvider是ContentProvider的子类,所以需要在AndroidManifest.xml文件中注册;并且需要编写xml文件描述可使用的文件夹目录,通过name 去映射文件真实目录,实现访问的安全性。

另外获取授权的方式有2种,

1.通过addFlags()来获取,仅使用setData,setDataandType以及setClipData方法传递uri时支持。

2.通过grantUrlPermission()方式,具体参考下文博客。

更多参考博客:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值