android n 打开文件夹,Android N 7.0 应用间共享文件(FileProvider)

Android N 中共享文件

Android N 系统,Android 框架执行的 StrictMode,API 禁止向您的应用外公开 file://URI。

如果一项包含文件 URI 的 Intent 离开您的应用,应用会停止运行,并出现 FileUriExposedException异常。

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

若要在应用间共享文件,您应发送一项 content://URI,并授予 URI 临时访问权限。

进行此授权的最简单方式是使用 FileProvider类。

如何共享文件

1、在AndroidManifest.xml中标签下添加如下代码

注意:

authorities:权限名称,可自己定义()

grantUriPermissions:必须是true,表示授予 URI 临时访问权限 ( readPermission, writePermission, and permission attributes)

exported:true: The provider is available to other applications. false: The provider is not available to other applications.

resource:自定义的xml文件(下面会介绍)

2、在res目录下新建一个xml文件夹,并且新建一个file_paths的xml文件(如下图)

0818b9ca8b590ca3270a3433284dd417.png

3、打开file_paths.xml文件添加如下内容

path:需要临时授权访问的路径(.代表所有路径)

name:给这个访问路径起个名字

代表的根目录: getCacheDir()

4、修改代码适配Android N

Intent intent = new Intent(Intent.ACTION_VIEW);

//判断是否是AndroidN以及更高的版本

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {

/* 这句要记得写:这是申请权限,之前因为没有添加这个,打开裁剪页面时,一直提示“无法修改低于50*50像素的图片”,开始还以为是图片的问题呢,结果发现是因为没有添加FLAG_GRANT_READ_URI_PERMISSION。 如果关联了源码,点开FileProvider的getUriForFile()看看,注释就写着需要添加权限。 */

intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

/*getUriForFile(Context context, String authority, File file):此处的authority需要和manifest里面保持一致。以前我们直接 Uri.fromFile(apkFile)构建出一个Uri,现在我们使用FileProvider.getUriForFile(); */

Uri contentUri = FileProvider.getUriForFile(context, 自定义的权限名, 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);

}

startActivity(intent);

下面FileProvider的getUriForFile()方法的注释:

/**

* Return a content URI for a given {@link File}. Specific temporary

* permissions for the content URI can be set with

* {@link Context#grantUriPermission(String, Uri, int)}, or added

* to an {@link Intent} by calling {@link Intent#setData(Uri) setData()} and then

* {@link Intent#setFlags(int) setFlags()}; in both cases, the applicable flags are

* {@link Intent#FLAG_GRANT_READ_URI_PERMISSION} and

* {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION}. A FileProvider can only return a

* content {@link Uri} for file paths defined in their

* meta-data element. See the Class Overview for more information.

*

* @param context A {@link Context} for the current component.

* @param authority The authority of a {@link FileProvider} defined in a

* {@code } element in your app's manifest.

* @param file A {@link File} pointing to the filename for which you want a

* content {@link Uri}.

* @return A content URI for the file.

* @throws IllegalArgumentException When the given {@link File} is outside

* the paths supported by the provider.

*/

public static Uri getUriForFile(Context context, String authority, File file) {

final PathStrategy strategy = getPathStrategy(context, authority);

return strategy.getUriForFile(file);

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值