发布网友 发布时间:2022-04-27 02:39
共1个回答
热心网友 时间:2022-06-24 22:45
1.首先,需要在清单文件中声明一个provider,如下:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.android.demo.fileProvider" // 名字,这个可以自行设置,通常都设置为包名.fileProvider
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/camera_path" /> // 在res下创建xml文件夹
</provider>
之所以需要声明,是因为FileProvider是身为Android四大组件之一的ContentProvider的子类,因此需要在清单文件中声明。
2.刚才的声明的最后一行,看到了一个xml文件。这个文件的作用是为FileProvider提供可以暴露的路径,一旦一个路径在文件中被声明,那么就可以被FileProvider提供。下面看一下这个xml文件中的内容:
<?xml version="1.0" encoding="utf-8"?><paths>
<external-path path="Demo/" name="Camera" /> // 外部存储,本文案例用的就是这个,注意这里的path就是共享的图片路径(我前面设置的文件路径就是外部存储下的Demo文件夹),name代表使用这个字段去访问真实的文件路径
// 以下是path可以设置的其他根节点路径 <root-path/> // 设备根目录,等同于直接new File("/") <files-path/> // 内部存储空间应用私有目录下的files/ 目录,等同于Context.getFilesDir() 所获取的目录路径 <cache-path/> // 内部存储空间应用私有目录下的cache/ 目录,等同于Context.getCacheDir() 所获取的目录路径 <external-files-path> // 外部存储空间应用私有目录下的files/ 目录,等同于Context.getExternalFilesDir(null) 所获取的目录路径 <external-cache-path> // 外部存储空间应用私有目录下的cache/ 目录,等同于Context.getExternalCacheDir()</paths>
应该很多朋友好奇为什么要将路径写到这么一个xml文件里。因为我们现在使用FileProvider来提供这个文件,而FileProvider是ContentProvider的子类,它用content:// Uri 代替了 file:/// Uri。因此需要通过path以及name一起来供FileProvider来找到文件的位置。这样也更加安全的向第三方程序提供文件内容了。
3.接下来,就来看看FileProvider类是如何帮助我们来调用系统相机的:
private void takePhoto7() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(this.getPackageManager()) != null) {
File file = new File(getCameraSavePath());
Uri uri = FileProvider.getUriForFile(this, "com.android.demo.fileProvider", file); // 主要就是这行代码,通过FileProvider获取文件的uri
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
this.startActivityForResult(intent, 1000);
}
}
getUriFromFile方法中的第二个参数就是我们在清单文件中声明的provider的authorities。(一定要一样)
4.在7.0的手机上运行后,就会发现成功的调用了系统的相机并实现了拍照。同时,可以打印出uri。我这个案例中的uri为:
content://com.android.demo.fileProvider/Camera/Camera.png