AndroidAndroid收藏集

Android 7.0 + FileProvider 访问隐私文

2019-07-18  本文已影响0人  12313凯皇

参考文章:android 7.0+ FileProvider 访问隐私文件 相册、相机、安装应用的适配

一、概述

Android 7.0 开始,Android SDK 中的 StrictMode 策略禁止开发人员在应用外部公开 file:// URI。具体表现为,当我们在应用中使用包含 file:// URIIntent离开自己的应用时,程序会发生FileUriExposedException异常
这里我们要使用到的 FileProvider,就是 ContentProvider 的一个特殊子类,帮助我们将访问受限的 file:// URI转化为可以授权共享的 content:// URI

简单来说就是在Android 7.0及以上机型中如果需要访问手机文件,那么必须使用 FileProvider来进行适配,否则程序会报错。

二、使用

  1. AndroidManifest.xml注册FileProvider
<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="${applicationId}.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/files_paths" />
</provider>

  1. src\main\res\xml\文件夹下创建对应的files_paths.xml文件
<!--files_paths.xml-->
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
   <!--此处的name可以随便取-->
    <external-path
        name="external_storage_root"
        path="."/>
    <external-files-path name="document" path="Documents"/>
    <external-files-path name="download" path="Download" />
    <external-files-path name="pictures" path="Pictures" />
</paths>

xml中元素必须包含一到多个子元素。这些子元素用于指定共享文件的目录路径,必须是这些元素之一:

  1. 使用FileProvider进行转换:
//注意此处的 第二个参数必须与 Manifest文件中Provider 的 android:authorities 一致
Uri contentUri = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".FileProvider", outputFile);

此处需要传进三个参数,第一参数是context上下文,第二个参数是FileProvider,必须与 AndroidManifest.xml文件中Provider的 android:authorities一致,第三个参数是file文件对象。

下面再放上一个例子

Intent intent = new Intent();
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction(Intent.ACTION_VIEW);
String type = MimeTypesTools.getMimeType(context, path);
File file = new File(path);
Uri uri;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    uri = FileProvider.getUriForFile(mContext, 
    //添加这一句表示对目标应用临时授权该Uri所代表的文件
    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);BuildConfig.APPLICATION_ID+".fileprovider", file);
}else {
    uri = Uri.fromFile(file);
}
intent.setDataAndType(uri, type);
context.startActivity(intent);

划重点!!
一定要给Intent加一个flag——Intent.FLAG_GRANT_READ_URI_PERMISSION,否则会报Permission Denial的错,当然7.0以下的机型是不需要的。

上一篇下一篇

猜你喜欢

热点阅读