| |
|
|
开发:
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图书馆 购物 三丰科技 阅读网 日历 万年历 2025年11日历 | -2025/11/29 3:08:00- |
|
| 网站联系: qq:121756557 email:121756557@qq.com IT数码 |