您的位置:首页 > 移动开发 > Android开发

Android FileProvider使用笔记

2019-08-07 17:53 1596 查看

在Android 7.0以后使用相册或者需要存储oss上下载下来的apk之类需要将文件存储到App外部存储的时候可能会报android.os.FileUriExposedException的错误,原因是在Android7.0以后Google加强了StrictMode的审查,以往可以通过file://uri访问文件的方式现在也被禁用了。FileProvider的使用如下所示。
第一步在清单文件(AndroidManifest.xml)中注册FileProvider。

<application
android:icon=""
.......
>
<provider
//name对应FileProvider类名
android:name="android.support.v4.content.FileProvider"
//authorities需要与FileProvider.getUriForFile()方法中的authority保持一致
android:authorities="${applicationId}.provider"
android:exported="false"
//允许临时开启文件访问权限
android:grantUriPermissions="true">
<meta-data
//name对应属性是一个固定的常量,填写下面这个就行
android:name="android.support.FILE_PROVIDER_PATHS"
//资源文件指向xml文件夹中的file_provider.xml文件
android:resource="@xml/file_provider" />
</provider>
.......
</application>

在res文件夹内创建xml文件夹,xml文件夹内创建file_provider.xml,file_provider.xml的内容如下。

<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-files-path name="abcd" path="efgh" />
</paths>

Path标签内设置对应的文件夹目录标签

files-path 对应 /data/data/<包名>/files
cache-path 对应 /data/data/<包名>/cache
external-path 对应 /storage/emulate/0
external-files-path 对应 /storage/emulate/0/Android/data/<包名>/files
external-cache-path 对应 /storage/emulate/0/Android/data/<包名>/cache
例如 <external-files-path name=“abcd” path=“efgh” />

path属性代表文件需要存储的文件夹,上面这行代码就代表存在某个文件(A.jpg)将A.jpg存储到/storage/emulated/0/Android/data/<包名>/files/efgh文件夹下,前提是FileProvider.getUriForFile()中的authority与清单文件中的authority保持一致。

name代表FileProvider.getUriForFile()获取到的Uri,上面这行代码就代表A.jpg的Uri为content://<authority>/abcd/A.jpg。

使用之前的步骤完成后,接下来在项目中使用。

Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
File photoFile = createFile();
Uri photoUri = FileProvider.getUriForFile(this, this.getPackageName() + ".provider", photoFile);
Log.e(TAG, photoUri.toString());
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
startActivityForResult(takePictureIntent, REQUEST_CODE);

private File createFile() {
String timeStamp = new SimpleDateFormat("yyyy-MM-dd HHmm", Locale.CHINESE).format(new Date());
File externalFilesDir = getExternalFilesDir("efgh");
File image = null;
try {
image = File.createTempFile(timeStamp, ".jpg", externalFilesDir);
mCurrentPhotoPath = image.getAbsolutePath();
Log.e(TAG, mCurrentPhotoPath);
} catch (IOException e) {
e.printStackTrace();
}
return image;
}

调用相机拍照将照片存入我们设置的efgh文件夹中
打印Log如下。

//图片绝对路径
E/MainActivity: /storage/emulated/0/Android/data/com.rick.flieproviderdemo/files/efgh/2019-08-07 17216833243804914530274.jpg
//图片uri
E/MainActivity: content://com.rick.flieproviderdemo.provider/abcd/2019-08-07%2017216833243804914530274.jpg
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: