由于android 11对存储空间进行了更新,导致无法进入裁剪或者裁剪后无法保存,返回路径等问题.

android 10以下可以参考:android 相机拍照,从相册中选择,裁剪图片

前面部分和之前的一样.

一,兼容android 7.0 在AndroidManifest.xml中先申请临时访问权限,样式和activity同级

        <providerandroid:name="android.support.v4.content.FileProvider"android:authorities="${applicationId}.fileProvider"android:exported="false"android:grantUriPermissions="true"><meta-dataandroid:name="android.support.FILE_PROVIDER_PATHS"android:resource="@xml/file_paths"/></provider>

二,申请权限

<uses-permission android:name="android.permission.CAMERA" />

三,打开相机需要动态申请权限

1,可使用google提供的权限库easypermissions动态权限库:https://github.com/googlesamples/easypermissions

详细用法自行百度,google

打开相机/相册

//mImagePath是保存图片的路径,建议放缓存路径,不用权限:getExternalCacheDir()
private Uri photoOutputUri = FileProvider7.getUriForFile(this, new File(mImagePath));/*** 打开相机*/private void openCamera() {Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);//拍照图片保存到指定的路径intent.putExtra(MediaStore.EXTRA_OUTPUT, photoOutputUri);startActivityForResult(intent, 2);}/*** 打开相册*/private void openPhoto() {//调用android的图库Intent i = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);startActivityForResult(i, 3);}
/*** 兼容android 7.0以上获取uri异常的工具类*/
public class FileProvider7 {/*** 获取uri** @param context* @param file* @return*/public static Uri getUriForFile(Context context, File file) {Uri fileUri = null;try {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {ContentValues contentValues = new ContentValues();contentValues.put(MediaStore.Images.Media.DATA, file.getAbsolutePath());contentValues.put(MediaStore.Images.Media.DISPLAY_NAME, file.getName());contentValues.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");fileUri = context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {fileUri = getUriForFile24(context, file);} else {fileUri = Uri.fromFile(file);}} catch (Exception e) {e.printStackTrace();}return fileUri;}/*** android 7.0以上获取uri的方法** @param context* @param file* @return*/private static Uri getUriForFile24(Context context, File file) {Uri fileUri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".fileProvider", file);return fileUri;}/*** uri转Sting** @param context Context* @param uri     Uri* @param path    文件路径*/public static void getFilePathString(Context context, Uri uri, String path) {try {InputStream is = context.getContentResolver().openInputStream(uri);if (is == null) {return;}File file = new File(path);file.createNewFile();FileOutputStream fos = null;if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {fos = new FileOutputStream(file);FileUtils.copy(is, fos);} else {ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();byte[] buffer = new byte[1024 * 10];while (true) {int len = is.read(buffer);if (len == -1) {break;}arrayOutputStream.write(buffer, 0, len);}arrayOutputStream.close();byte[] dataByte = arrayOutputStream.toByteArray();if (dataByte.length > 0) {fos = new FileOutputStream(file);fos.write(dataByte);}}if (fos != null)fos.close();if (is != null)is.close();} catch (IOException e) {e.printStackTrace();}}/*** 安装app的操作,兼容7.0** @param context* @param intent* @param type      执行的意图(application/vnd.android.package-archive-->安装app)* @param file* @param writeAble 是否需要写操作*/public static void setIntentDataAndType(Context context, Intent intent, String type, File file, boolean writeAble) {if (Build.VERSION.SDK_INT >= 24) {intent.setDataAndType(getUriForFile(context, file), type);intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);if (writeAble) {intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);}} else {intent.setDataAndType(Uri.fromFile(file), type);}}
}

核心部分:android 11获取uri的方式通过ContentValues转换

拍照/相册成功后返回

 @Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);Intent intent;if (resultCode == RESULT_OK) {switch (requestCode) {//拍照完成,去裁剪case 2:if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {intent = PhotoUtils.startPhotoZoom(photoOutputUri, photoOutputUri, 100);} else {intent = PhotoUtils.startPhotoZoom(photoOutputUri, mImagePath, 100);}startActivityForResult(intent, 4);break;//相册完成,去裁剪case 3:if (null != data) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {intent = PhotoUtils.startPhotoZoom(data.getData(), photoOutputUri, 100);} else {intent = PhotoUtils.startPhotoZoom(data.getData(), mImagePath, 100);}startActivityForResult(intent, 4);}break;//裁剪完成,保存,上传case 4:new Thread(() -> {FileProvider7.getFilePathString(mContext, photoOutputUri, mImagePath);mHandler.sendEmptyMessage(UPDATA_MSG);}).start();break;default:break;}}}
public class PhotoUtils {/*** 调用系统裁剪** @param uri        需要裁剪的图片路径* @param mImagePath 图片输出路径* @param size       裁剪框大小*/public static Intent startPhotoZoom(Uri uri, Uri mImagePath, int size) {return startPhotoZoom(uri, mImagePath, size, size);}public static Intent startPhotoZoom(Uri uri, String mImagePath, int size) {return startPhotoZoom(uri, Uri.fromFile(new File(mImagePath)), size, size);}/*** 调用系统裁剪<br>* 注:华为手机默认** @param uri        需要裁剪的图片路径* @param mImagePath 图片输出路径* @param sizeX      裁剪x* @param sizeY      裁剪y*/public static Intent startPhotoZoom(Uri uri, Uri mImagePath, int sizeX, int sizeY) {Intent intent = new Intent("com.android.camera.action.CROP");if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {//添加这一句表示对目标应用临时授权该Uri所代表的文件intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);//intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);}//裁剪后输出路径intent.putExtra(MediaStore.EXTRA_OUTPUT, mImagePath);//输入图片路径intent.setDataAndType(uri, "image/*");intent.putExtra("crop", "true");
//        intent.putExtra("circleCrop", "true");intent.putExtra("aspectX", 9998);//2019/5/8 修复华为手机默认为圆角裁剪的问题intent.putExtra("aspectY", 9999);//intent.putExtra("outputX", sizeX);intent.putExtra("outputY", sizeY);intent.putExtra("scale", true);intent.putExtra("scaleUpIfNeeded", true);intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());intent.putExtra("return-data", false);return intent;}}

裁剪完成返回的是uri,如果只是用于显示可以直接使用uri显示.如果需要上传,需要本地路径,就需要通过转换一下.

FileProvider7.getFilePathString(mContext, photoOutputUri, mImagePath);

mImagePath就是图片本地路径,可以用于显示,上传,保存等操作,由于进行了IO操作,建议在子线程处理.

笔记备忘, 请多指教

兼容Android 11 相机拍照,从相册中选择,裁剪图片相关推荐

  1. Android 拍照以及相册中选择(适配高版本)————上传多张照片之压缩处理、在线预览可伸缩放大(二)

    ______ Introduction ______ 前言 上一篇文章刚给大家总结完,关于上传头像的功能.此文章所述 主要是关于上传头像的具体流程以及如何对照片做裁剪处理,回调给控件显示:当然重中之重 ...

  2. uni-app用uni.chooseImage API调用相机或从相册中选择图片

    uni-app用uni.chooseImage API调用相机或从相册中选择图片 chooseImage: function() {var _this = this;uni.chooseImage({ ...

  3. Android实现相机拍照和相册选择以及图片裁剪适配Android10以上

    之前写的一个工具类,在华为手机Android版本12上无法返回图片路径,提示不是一个文件或是文件不存在. 所以更改此工具类如下: package com.suoer.comeonhealth.laib ...

  4. 微信小程序 拍照/从相册中选择图片

    微信小程序提供的众多API中,wx.chooseImage函数就是用来访问手机相册或摄像头的.调用该函数后,界面下方会呼出一个菜单,可以分别选择进入相册挑选已有照片或是打开摄像头进行拍照: 我们往WX ...

  5. php拍照从手机相册中选择,Android获取图片:拍照和从相册中选择

    概述 在Android开发中获取图片主要包括如下两种方式: 打开相机拍照 从图库中选择图片 一.打开相机拍照 打开相机拍照主要包括如下几个部分: 权限申请 打开摄像头 拍照后传回数据处理 1. 权限申 ...

  6. android点击选择相册,android: 从相册中选择照片

    虽然调用摄像头拍照既方便又快捷,但并不是每一次我们都需要去当场拍一张照片的. 因为每个人的手机相册里应该都会存有许许多多张照片,直接从相册里选取一张现有的照 片会比打开相机拍一张照片更加常用.一个优秀 ...

  7. Android中拍照(相册中选择)并上传图片功能(包括动态获取权限)

    作为新手小白,为了实现这个拍照和相册选取图片并上传功能,确实花费了很多时间,因为实现不容易,所以记录下来,一和大家分享,二为之后学习做个备忘. 一.实现效果 二. 整体思路 Android手机客户端, ...

  8. Android中拍照完就给图片加水印,Android调用相机拍照并添加水印

    最近项目提出新需求,要求在拍照后在图片上添加用户信息的水印,so,楼主重新整理封装了一个简单的拍照+水印的工具类,需求不同,仅供参考.文件操作及权限做了适配,支持androidN及以上版本,放心使用. ...

  9. Android开发之调用相机拍照与本地图库选择图片

    引用链接 Android开发之调用相机拍照与本地图库选择图片 Android调用相机实现拍照功能 部分截图 引言 小项目有一个访问相册的需求,在网上查找得到两位大神博客指点,但博客发布时间过旧,难免因 ...

最新文章

  1. 我们不要框计算 我们要更好的搜索体验
  2. python最快的循环方法_【转】【Python效率】五种Pandas循环方法效率对比
  3. 图片上传压缩android,android 图片上传压缩常见问题分析
  4. html jq 控制显示密码,js、jquery分别实现点击密码输入框密码显示和隐藏
  5. 02 理解==与Equals()的区别及用法 1214
  6. Git/Git-flow使用心得
  7. yum安装virtualbox_CentOS7安装virtualbox
  8. Java基础学习总结(44)——10个Java 8 Lambda表达式经典示例
  9. STM32系列单片机在进入main函数前都在干些什么?
  10. 网景R6400做无线中继服务器,网件R6400刷梅林后5G掉线假死怎么办解决办法
  11. for循环及判断语句的20个经典习题
  12. 2021年中国银行业金融机构普惠型小微企业贷款情况分析:贷款余额不断增加,增速也不断下降[图]
  13. H3C和锐捷如何查看光衰
  14. 动态可视化十大排序算法之冒泡排序
  15. 如何正确使用Pandas库提升项目的运行速度?
  16. Python之 - 使用Scrapy建立一个网站抓取器,网站爬取Scrapy爬虫教程
  17. 发送手机验证码,验证手机验证码,包括数据表的设计
  18. Linux基础之的权限数字含义
  19. VSC/SMC(十四)——全局快速Terminal滑模控制(含程序模型)
  20. 13.深度学习之RNN进阶-1

热门文章

  1. 原生JS实现 ‘Tab栏切换’,‘手风琴’,‘轮播图’效果
  2. spring cache annotation(二)
  3. 微信小程序点击事件失效
  4. 审慎 合宜与慈善三种学派的分类与核心思想
  5. 从网上下载一个vue项目,跑起来的全过程
  6. vba 添加outlook 签名_如何在Outlook中添加默认签名
  7. 励志语录(忙碌的同时也要停下来思考人生)
  8. Android 学习笔记(十二):安卓中的事件分发机制
  9. 电子木鱼 微信小程序源码 今天你积功德了吗?
  10. 品牌的成功取决于质量的好坏