【随心笔录】Android N 文件Uri传递,报出FileUriExposedException异常,使用FileProvider

来源:互联网 发布:2017淘宝装修教程 编辑:程序博客网 时间:2024/05/22 16:44

一、问题原因

  • 报出FileUriExposedException异常,官网上搜索,发现在Android N的behavior-changes里面,有一些关于 FileUriExposedException 异常的描述:
    • 对于面向 Android N 的应用,Android 框架执行的 StrictMode,API 禁止向您的应用外公开 file://URI。
      如果一项包含文件 URI 的 Intent 离开您的应用,应用失败,并出现 FileUriExposedException异常。
    • 若要在应用间共享文件,您应发送一项 content://URI,并授予 URI临时访问权限。
      进行此授权的最简单方式是使用 FileProvider类。 如需有关权限和共享文件的更多信息,
      请参阅共享文件。
  • 也就是说,对于应用间共享文件这块,Android N中做了强制性要求。

二.解决步骤

1.要用到类:android.support.v4.content.FileProvider

  • 在清单文件AndroidManifest.xml里面注册这个provider,注册如下:
<provider    android:authorities="app包名.android7.fileprovider" //个人解释:权限字符串,唯一就行    android:name="android.support.v4.content.FileProvider"    android:exported="false"    android:grantUriPermissions="true">    <meta-data android:name="android.support.FILE_PROVIDER_PATHS"        android:resource="@xml/file_paths"/> //resource中的@xml/file_paths是我们接下来要添加的文件</provider>

2.file_paths.xml文件

  • 在res文件下新增xml文件,新建file_paths.xml。
<?xml version="1.0" encoding="utf-8"?><paths xmlns:android="http://schemas.android.com/apk/res/android">    <root-path        name="root"        path="" />    <files-path        name="files"        path="" />    <cache-path        name="cache"        path="" />    <external-path        name="external"        path="" />    <external-files-path        name="external-file-path"        path="" />    <external-cache-path        name="external-cache-path"        path="" /></paths>

3.使用工具类FileProvider7

import android.content.Context;import android.content.Intent;import android.net.Uri;import android.os.Build;import java.io.File;public class FileProvider7 {    public static Uri getUriForFile(Context context, File file) {        Uri fileUri = null;        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {            fileUri = getUriForFile24(context, file);        } else {            fileUri = Uri.fromFile(file);        }        return fileUri;    }    private static Uri getUriForFile24(Context context, File file) {        return android.support.v4.content.FileProvider.getUriForFile(context, "app包名.android7.fileprovider", file);    }    public static void setIntentDataAndType(Context context, Intent intent, String type, File file, boolean writeAble) {        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {            intent.setDataAndType(getUriForFile(context, file), type);            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);            if (writeAble) {                intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);            }        } else {            intent.setDataAndType(Uri.fromFile(file), type);        }    }}

4.使用

(1)拍照
//Android N 使用FileProviderIntent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);if (intent.resolveActivity(getPackageManager()) != null) {    Uri imageUri = FileProvider7.getUriForFile(context, new File(Environment.getExternalStorageDirectory(), FileManager.SaveCameraPath() + name));    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);    } else {        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);    }    // 指定照片保存路径(SD卡)    intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);    startActivityForResult(intent, CAMERA_WITH_DATA);}
阅读全文
1 0
原创粉丝点击