| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 移动开发 -> Android 调用系统裁剪,适配11和12及手机 -> 正文阅读 |
|
[移动开发]Android 调用系统裁剪,适配11和12及手机 |
前言:发现Android 调用系统裁剪时,在各Android 版本出现各种问题,踩了一堆坑,做一下总结,免得以后忘记 后面会有完整裁剪代码 1,一加手机报错intent.putExtra("outputFormat", "png"); 这句不能加,否则报错 2,Android 12不能进入裁剪页面不能加 intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 否则无法进入裁剪页面 3.Android 12裁剪后无法拿到图片显示? Android11,12申请权限 <!-- 读取您的USB存储设备中的内容 --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <!-- 修改或删除您的USB存储设备中的内容 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 申请这两个权限,在手机上只会申请媒体文件的访问权限,无法访问全部文件权限,这很重要 全部权限需要用户手动给予 <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" /> 如果用户愿意手动给你这个权限,那么裁剪就不会出现问题,否则就会出现裁剪成功,保存不成功的现象 出现这个原因:我们拥有媒体权限,所以可以打开相册选择图片,进行裁剪,裁剪后的图片会在文件夹,他不属于媒体文件,我们没有这个权限,除非有全部文件权限 解决方案:我们将裁剪后的图片加入到相册,这样裁剪后图片就是媒体文件了,代码后续会放上 4.谷歌手机路劲和普通手机不一致这个要注意一下,谷歌手机最好不要用bundle的形式去拿裁剪后的图片 下面是源码部分?1.打开相册 Intent intent = new Intent(Intent.ACTION_PICK);//选择数据的意图 intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, IMAGE_UNSPECIFIED);//设置数据和类型,从图库中获取图片 startActivityForResult(intent, PHOTOZOOM);//执行意图并传入请求码(请求码根据业务需要自行指定) 2.拿到相册uri后进行裁剪 data.getData()是uri
裁剪和得到裁剪拿到图片可以用两种写法 1,用bundle的方式, 优点就是不要读写权限了 缺点就是对裁剪尺寸有限制(500*500),因为intent传值,大小1M,多了报错 2.就用uri了 优点大小无限制 缺点就是要权限 1,uri方式 private void clipPhoto(Uri uri) { Intent intent = new Intent("com.android.camera.action.CROP"); intent.setDataAndType(uri, "image/*"); // 下面这个crop=true是设置在开启的Intent中设置显示的VIEW可裁剪 intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.putExtra("crop", "true"); intent.putExtra("aspectX", 1); intent.putExtra("aspectY", 1); intent.putExtra("outputX", 800); intent.putExtra("outputY", 800); intent.putExtra("return-data", false); intent.putExtra("scale", true); intent.putExtra("scaleUpIfNeeded", true); File CROP_TEMP_FILE = Environment.getExternalStorageDirectory(); File mFullPath = new File(CROP_TEMP_FILE, "unheadimage" + System.currentTimeMillis() + ".png"); fileUri = Uri.fromFile(mFullPath); intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); startActivityForResult(intent, PHOTORESULT); } 2.bundle方式 private void clipPhoto(Uri uri) { Intent intent = new Intent("com.android.camera.action.CROP"); intent.setDataAndType(uri, "image/*"); // 下面这个crop=true是设置在开启的Intent中设置显示的VIEW可裁剪 intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.putExtra("crop", "true"); // aspectX aspectY 是宽高的比例 intent.putExtra("aspectX", 1); intent.putExtra("aspectY", 1); // outputX outputY 是裁剪图片宽高 intent.putExtra("outputX", 100); intent.putExtra("outputY", 100); intent.putExtra("circleCrop", true); intent.putExtra("return-data", true); startActivityForResult(intent, PHOTORESULT); } 3.对裁剪的图片处理 同样分2种 1.uri方式 sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, fileUri)); new Handler().postDelayed(new Runnable() { @Override public void run() { try { iView.setImageBitmap(MediaStore.Images.Media.getBitmap(getContentResolver(),fileUri)); } catch (IOException e) { e.printStackTrace(); } } },500); 其中发送广播是为了将图片变成媒体文件,否则他是文件,需要文件权限 2.bundle方式 Bundle bundle = data.getExtras();//把数据取出来,Bundle是一个装数据的可以在activity之间传输的类 Bitmap bitmap = bundle.getParcelable("data");//获取位图 iView.setImageBitmap(bitmap);//设置位图,显示 下面提供一种uri转bitmap的 1, MediaStore.Images.Media.getBitmap(getContentResolver(),fileUri) 2. private Bitmap getBitmapFromUri(Context context, Uri uri) { ParcelFileDescriptor parcelFileDescriptor; Bitmap mBitmap = null; try { parcelFileDescriptor = context.getContentResolver() .openFileDescriptor(uri, "r"); FileDescriptor fileDescriptor = parcelFileDescriptor .getFileDescriptor(); mBitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor); parcelFileDescriptor.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return mBitmap; } 在提供一种保存bitmap进相册的 public static void saveImageToGallery(Context context, Bitmap bmp) { // 首先保存图片 File appDir = new File(Environment.getExternalStorageDirectory(), "Boohee"); if (!appDir.exists()) { appDir.mkdir(); } String fileName = System.currentTimeMillis() + ".jpg"; File file = new File(appDir, fileName); try { FileOutputStream fos = new FileOutputStream(file); bmp.compress(Bitmap.CompressFormat.JPEG, 100, fos); fos.flush(); fos.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } // 其次把文件插入到系统图库 // try { // MediaStore.Images.Media.insertImage(context.getContentResolver(), // file.getAbsolutePath(), fileName, null); // } catch (FileNotFoundException e) { // e.printStackTrace(); // } // 最后通知图库更新 context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + file.getPath()))); } 完结散花,后续遇到问题,继续完善 ----------------------------------------------------------------------------- 补充点: 3.Android 12裁剪后无法拿到图片显示 这个问题新的修改方案 因为intent的建立的文件夹有问题,上面是用的私有域地址,可以用公有域的 可以用getExternalStoragePublicDirectory 获取公域地址方法: String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getPath() |
|
移动开发 最新文章 |
Vue3装载axios和element-ui |
android adb cmd |
【xcode】Xcode常用快捷键与技巧 |
Android开发中的线程池使用 |
Java 和 Android 的 Base64 |
Android 测试文字编码格式 |
微信小程序支付 |
安卓权限记录 |
知乎之自动养号 |
【Android Jetpack】DataStore |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 23:51:47- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |