写点什么

Android 相册选择图片、相机拍照上传功能实现(上)

用户头像
Android架构
关注
发布于: 17 小时前

========




准备工作


因为我们要读取存储给拍照图片一个存储位置,所以我们需要先创建 FileProvider,为什么要用 FileProvider 而不直接用 File 是因为,从 Android N 7.0 之后,为了保证 App 间传输文件的安全性,不在允许直接用 file://


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


传递,会 Crash 并抛出 FileUriExposedException,所以要临时授予权限通过 URI 访问。(Ps:可能理解不到位,深入了解可自行查询,这里简单说明下)


所以,在正式写相机拍照之前,我们先搞一下 FileProvider。

FileProvider

FileProvider 的使用也比较简单。分为三步。


  1. AndroidManifest.xml 中定义 FileProvider

  2. 创建 XML 文件说明临时授予权限的路径

  3. 使用 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 后,继续正题。

三、相机正文

  1. 创建拍照存储路径

  2. 拉起相机拍照

  3. 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 实现上传功能。

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
Android相册选择图片、相机拍照上传功能实现(上)