参考地址:

1、引入依赖

在Project的build.gradle在添加以下代码

 allprojects {repositories {...maven { url 'https://jitpack.io' }}}

在Module的build.gradle在添加以下代码

 implementation 'com.github.donkingliang:ImageSelector:2.2.1'

从2.0.0版本开始,库迁移androidx。没有使用androidx的项目可以使用1.9.3版本。

2、配置AndroidManifest.xml

注意: 1.7.0版本后,不需要再配置FileProvider,ImageSelector内部已经配置了。

//储存卡的读写权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
//调用相机权限
<uses-permission android:name="android.permission.CAMERA" />//图片选择Activity
<activity android:name="com.donkingliang.imageselector.ImageSelectorActivity"//去掉Activity的ActionBar。//使用者可以根据自己的项目去配置,不一定要这样写,只要让Activity的ActionBar去掉就可以了。android:theme="@style/Theme.AppCompat.Light.NoActionBar"//横竖屏切换处理。//如果要支持横竖屏切换,一定要加上这句,否则在切换横竖屏的时候会发生异常。android:configChanges="orientation|keyboardHidden|screenSize"/>//图片预览Activity
<activity android:name="com.donkingliang.imageselector.PreviewActivity"android:theme="@style/Theme.AppCompat.Light.NoActionBar"android:configChanges="orientation|keyboardHidden|screenSize"/>//图片剪切Activity
<activityandroid:name="com.donkingliang.imageselector.ClipImageActivity"android:theme="@style/Theme.AppCompat.Light.NoActionBar" /><!-- Android 7.0 文件共享配置,1.7.0之前必须配置,1.7.0后不需要 -->
<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>

在res/xml文件夹下创建file_paths.xml文件(名字可以自己定义)

<?xml version="1.0" encoding="utf-8"?>
<paths><!-- 这个是保存拍照图片的路径,必须配置。 --><external-pathname="images"path="Pictures" />
</paths>

3、调起图片选择器

ImageSelector支持图片的单选、限数量的多选和不限数量的多选。还可以设置是否使用相机、是否剪切图片等配置。ImageSelector提供了统一的调起相册的方法。

 //单选ImageSelector.builder().useCamera(true) // 设置是否使用拍照.setSingle(true)  //设置是否单选.canPreview(true) //是否可以预览图片,默认为true.start(this, REQUEST_CODE); // 打开相册//限数量的多选(比如最多9张)
ImageSelector.builder().useCamera(true) // 设置是否使用拍照.setSingle(false)  //设置是否单选.setMaxSelectCount(9) // 图片的最大选择数量,小于等于0时,不限数量。.setSelected(selected) // 把已选的图片传入默认选中。.canPreview(true) //是否可以预览图片,默认为true.start(this, REQUEST_CODE); // 打开相册//不限数量的多选
ImageSelector.builder().useCamera(true) // 设置是否使用拍照.setSingle(false)  //设置是否单选.setMaxSelectCount(0) // 图片的最大选择数量,小于等于0时,不限数量。.setSelected(selected) // 把已选的图片传入默认选中。.canPreview(true) //是否可以预览图片,默认为true.start(this, REQUEST_CODE); // 打开相册//单选并剪裁
ImageSelector.builder().useCamera(true) // 设置是否使用拍照.setCrop(true)  // 设置是否使用图片剪切功能。.setCropRatio(1.0f) // 图片剪切的宽高比,默认1.0f。宽固定为手机屏幕的宽。.setSingle(true)  //设置是否单选.canPreview(true) //是否可以预览图片,默认为true.start(this, REQUEST_CODE); // 打开相册//仅拍照
ImageSelector.builder().onlyTakePhoto(true)  // 仅拍照,不打开相册.start(this, REQUEST_CODE);//拍照并剪裁
ImageSelector.builder().setCrop(true) // 设置是否使用图片剪切功能。.setCropRatio(1.0f) // 图片剪切的宽高比,默认1.0f。宽固定为手机屏幕的宽。.onlyTakePhoto(true)  // 仅拍照,不打开相册.start(this, REQUEST_CODE);

REQUEST_CODE就是调用者自己定义的启动Activity时的requestCode,这个相信大家都能明白。selected可以在再次打开选择器时,把原来已经选择过的图片传入,使这些图片默认为选中状态。

如果是仅拍照模式(onlyTakePhoto = true)时,useCamera无论设置什么,都是为true。

4、接收选择器返回的数据

在Activity的onActivityResult方法中接收选择器返回的数据。

    @Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);if (requestCode == REQUEST_CODE && data != null) {//获取选择器返回的数据ArrayList<String> images = data.getStringArrayListExtra(ImageSelector.SELECT_RESULT);/*** 是否是来自于相机拍照的图片,* 只有本次调用相机拍出来的照片,返回时才为true。* 当为true时,图片返回的结果有且只有一张图片。*/boolean isCameraImage = data.getBooleanExtra(ImageSelector.IS_CAMERA_IMAGE, false);}}

ImageSelector.SELECT_RESULT是接收数据的key。数据是以ArrayList的字符串数组返回的,就算是单选,返回的也是ArrayList数组,只不过这时候ArrayList只有一条数据而已。ArrayList里面的数据就是选中的图片的文件路径。

适配android 10

兼容android 10的手机请使用1.7.0版本。

由于android 10不允许应用直接访问外部文件,所以在android 10及以上的手机,ImageSelect返回的图片链接可能无法直接加载,因为ImageSelector返回的是图片在手机里的地址。但是可以通过uri进行加载,ImageSelector内部提供了一些方法可以供外部使用,用于适配android 10。

如何在Android 10加载手机本地图片,请看我的这篇博客。

//是否是android 10及以上
VersionUtils.isAndroidQ();// android 10可以通过图片uri加载手机本地图片。//图片链接转uri
Uri uri = UriUtils.getImageContentUri(Context context, String path);//通过uri加载图片Glide.with(mContext).load(uri).into(ivImage);ivImage.setImageURI(uri);// 或者
Bitmap bitmap = ImageUtil.getBitmapFromUri(Context context, Uri uri);

注意: 剪切返回的图片的图片链接是放在应用的私有目录的,所以剪切返回的图片可以直接用path加载,不需要转成uri再加载。ImageSelector提供了判断图片链接是否是剪切的图片的方法。

// 是否是剪切返回的图片
ImageUtil.isCutImage(mContext, path);

图片预加载和缓存

由于从手机中加载图库是个耗时操作,图片太多时,打开图库可能等待时间过长,用户体验不好。所以在2.1.0版本和1.9.0版本开始,提供了预加载手机图片并缓存的功能。你可以在用户打开图片选择器前,预先加载手机图片,这样在用户打开图片选择器时,会直接从缓存中读取图片列表,大大提升选择器的加载速度。

选择器默认不开启预加载并缓存功能,如果需要预加载,请调用下面的方法:

ImageSelector.preload(context);

调用这个方法的时机没有特殊的要求,只要是在打开选择器前调用就可以了。

注意: 由于加载手机图片需要申请WRITE_EXTERNAL_STORAGE权限,所以在调用该方法前,请确保权限已申请。

在选择器使用完毕,不再需要时,可以调用下面方法清空缓存:

ImageSelector.clearCache(context);

清空缓存的操作不是必须的,如果不清空,缓存会一直保留,直到app被回收。因为缓存的是图片的路径,所以不会占用太多的内存

显示图片问题

不过我们可以通过图片uri来加载图片,这种方式在Android 10也是可以的。 先将图片路径转换成uri 。

    public static Uri getImageContentUri(Context context, String path) {Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,new String[] { MediaStore.Images.Media._ID }, MediaStore.Images.Media.DATA + "=? ",new String[] { path }, null);if (cursor != null && cursor.moveToFirst()) {int id = cursor.getInt(cursor.getColumnIndex(MediaStore.MediaColumns._ID));Uri baseUri = Uri.parse("content://media/external/images/media");return Uri.withAppendedPath(baseUri, "" + id);} else {// 如果图片不在手机的共享图片数据库,就先把它插入。if (new File(path).exists()) {ContentValues values = new ContentValues();values.put(MediaStore.Images.Media.DATA, path);return context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);} else {return null;}}}
复制代码

然后就可以直接通过图片uri加载图片了。

Bitmap bitmap = getBitmapFromUri(context, uri);
// 通过uri加载图片
public static Bitmap getBitmapFromUri(Context context, Uri uri) {try {ParcelFileDescriptor parcelFileDescriptor =context.getContentResolver().openFileDescriptor(uri, "r");FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor);parcelFileDescriptor.close();return image;} catch (Exception e) {e.printStackTrace();}return null;}// Glide使用uri加载图片
Glide.with(mContext).load(uri).into(imageView); //setImageURI
imageView.setImageURI(uri);

参考文献:
https://github.com/donkingliang/ImageSelectorhttps://github.com/donkingliang/ImageSelector

Android 图片选择框架ImageSelector适配Android10及以上相关推荐

  1. Android图片选择框架

    1.今天做开发,需要一个相册多选功能,然后就上网查了一下,看了有一个jar包,可以直接引用,就直接调用了, com.yanzhenjie:album:1.0.0 本来想直接写一个左右循环移动的方法,但 ...

  2. android好用拍照框架,Github挺好用的android图片选择框架(拍照+从相册)

    项目要用到多图片上传选择和展示的功能,在github找到了个效果看起来不错的demo,悲剧的是下载完zip后浏览器卡死了,没记住地址,如有侵权请联系... 话不多少,先看效果: 这个库叫做 Photo ...

  3. Github挺好用的android图片选择框架(拍照+从相册)

    项目要用到多图片上传选择和展示的功能,在github找到了个效果看起来不错的demo,悲剧的是下载完zip后浏览器卡死了,没记住地址,如有侵权请联系... 话不多少,先看效果: 这个库叫做 Photo ...

  4. 一款现代、高效的 Android 图片压缩框架

    本项目主要基于 Android 自带的图片压缩 API 进行实现,提供了开源压缩方案 Luban 和 Compressor 的实现,解决了单一 Fie 类型数据源的问题,并在它们的基础之上进行了功能上 ...

  5. Android系统(74)--- 从零实现灵活且可高度定制的Android图片选择架构

    从零实现灵活且可高度定制的Android图片选择架构 https://www.jianshu.com/u/df76f81fe3ff 前言 这是我花费了数月闲暇时间从零开始写的一个库,在这期间,我学习到 ...

  6. Android图片缓存框架Glide

    Android图片缓存框架Glide Glide是Google提供的一个组件.它具有获取.解码和展示视频剧照.图片.动画等功能.它提供了灵活的API,帮助开发者将Glide应用在几乎任何网络协议栈中. ...

  7. Android 图片选择对话框,通过本地相册或照相机获得图片,可单选或多选,单选可设置是否裁剪

    AndroidPickPhotoDialog 项目地址: wanliyang1990/AndroidPickPhotoDialog 简介:Android 图片选择对话框,通过本地相册或照相机获得图片, ...

  8. 一款漂亮的图片选择框架

    介绍 拍照,从相册选取图片,相信这是大多数APP都会用到的功能,这些代码又臭又重复, 于是最近我自己用kotlin写了一款漂亮而简单的图片选择框架. 首先看效果图: 使用 使用起来也很方便,看代码: ...

  9. android微信图片选择框架,Android仿微信图片选择器ImageSelector使用详解

    今天给大家介绍一个仿微信的图片选择器:ImageSelector.ImageSelector支持图片的单选.限数量的多选和不限数量的多选.支持图片预览和图片文件夹的切换.在上一篇文章 <Andr ...

最新文章

  1. 人工智能及其应用(第5版).蔡自兴-3章课后习题。【参考答案】
  2. Java基础篇:JDBC核心技术
  3. DXPerience6.x 使用体会(二)
  4. 10 个小技巧:快速用 Python 进行数据分析
  5. php mysql inner join,inner join用法是什么
  6. fputc会覆盖吗_深覆盖 VS 深覆合如何区分?这一篇看完就都明白了!
  7. C#使用Log4Net记录日志【转】
  8. Kubernetes NetworkPolicy 工作原理浅析
  9. 负载均衡和反向代理的通俗理解
  10. Mysql学习总结(49)——从开发规范、选型、拆分到减压
  11. 因严重缺陷,Rust 撤销所有 Crates 包的 API 令牌
  12. 降到3折的EasyRecovery了解下?
  13. python 绘图sns.distplot
  14. Android Fragment学习
  15. 时钟模块ds1302的使用
  16. python 中文官方手册
  17. 3DMax制作下雨场景
  18. 苹果充电显示不支持此配件_水果手机充电时,显示不支持此配件时的应急处理小窍门...
  19. 越权问题解决优化方案
  20. ABAP 中历史库存

热门文章

  1. 夸西莫多的一首短诗--《瞬息间是夜晚》
  2. 删除cookie,domain的设置
  3. 功能测试之游戏动态测试
  4. Cisco系列路由器密码恢复研究与实践
  5. 洛谷:珠心算测验(P2141)C语言
  6. 你的模型是最好的还是最幸运的?选择最佳模型时如何避免随机性
  7. matlab dms2degrees,Convert degrees-minutes to degrees
  8. 无界函数的反常积分的收敛法
  9. pytorch FX模型静态量化
  10. 批量将多个 PPT 幻灯片文件合并成单个 PPT 文件