Android 相册选择图片、相机拍照上传功能实现(上)
========
准备工作
因为我们要读取存储给拍照图片一个存储位置,所以我们需要先创建 FileProvider,为什么要用 FileProvider 而不直接用 File 是因为,从 Android N 7.0 之后,为了保证 App 间传输文件的安全性,不在允许直接用 file://
传递,会 Crash 并抛出 FileUriExposedException,所以要临时授予权限通过 URI 访问。(Ps:可能理解不到位,深入了解可自行查询,这里简单说明下)
所以,在正式写相机拍照之前,我们先搞一下 FileProvider。
FileProvider
FileProvider 的使用也比较简单。分为三步。
AndroidManifest.xml 中定义 FileProvider
创建 XML 文件说明临时授予权限的路径
使用 FileProvider
下面作简单说明
第一步:
分别说明下含义
name:FileProvider 继承自 ContentProvider,原来是 v4 下的包,现在都在 androidx 下了。
authorities:作用是用来标识,命名方式是 APP 包名 + provider 名的形式
exported:是否公开
grantUriPermissions:是否授予临时权限
然后是 meta-data,由于我们不能直接使用 File,而要使用 URI,那么就需要配置文件对真实存储位置做一个映射。这个 resource 就是我们的映射配置文件,也就是哪些路径要授权写在这文件中。
第二步:
在 res 目录下创建 xml 文件夹再创建 file_paths.xml 文件。位置:res/xml/file_paths.xml
<?xml version="1.0" encoding="utf-8"?><paths><external-path /></paths>
因为我比较懒,就直接从根目录授权,用 . 表示。
第三步:
最后就在代码中使用了
// 直接通过该方法就可以得到 URIUri uri = FileProvider.getUriForFile(this, "在 AndroidManifest.xml 中声明的标识", file));
OK,简单了解 FileProvider 后,继续正题。
三、相机正文
创建拍照存储路径
拉起相机拍照
onActivityResult 回调处理
第一步:
我们要给拍出的照片一个存储路径才能存储
// 创建照片存储目录 ScreenUtils.getFilePath 方法是一个工具类,下面有具体代码 File imgDir = new File(ScreenUtils.getFilePath(this, null));// 创建照片 String photoName = System.currentTimeMillis() + ".png";File picture = new File(imgDir, photoName);if (!picture.exists()) {try {picture.createNewFile();} catch (IOException e) {Log.e(TAG, "choosePictureTypeDialog: 创建图片失败", e);}}// 该路径在回调时获取图片用到 imgPath = picture.getAbsolutePath();
第二步:
创建 Intent 拉起相机
// 调用相机拍照 Intent camera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);camera.putExtra(MediaStore.EXTRA_OUTPUT, FileProvider.getUriForFile(this, "AndroidManifest 中声明的 fileprovider 标识", picture));startActivityForResult(camera, type);
第三步:
回调逻辑处理
@Overrideprotected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {super.onActivityResult(requestCode, resultCode, data);// 拉起相机回调 data 为 null,打开相册回调不为 null,这里没有判空 Glide.with(this).load(imgPath).skipMemoryCache(true).diskCacheStrategy(DiskCacheStrategy.NONE).into(imageView);}到此,从相册选择图片和从相机拍照都已经完成了。完整代码 GitHub 地址
下篇 Blog 实现上传功能。
评论