Android实现简单图库辅助器
发布时间 - 2026-01-11 00:32:11 点击率:次写在前面

实际开发经常会遇到读取相册或者拍照功能,网上也很非常多图库框架,都各有风格,也因此与自己的项目格格不入。再者,框架API太多,需要的配置太多,还要吃力研究。所以,本人摸索大多图库框架,提炼核心,写一个只提供核心的辅助类,剩下的就可以自行玩耍。
实现步骤
第一步,创建辅助类,使用弱引用持有Activity,防止内存溢出。
public class GalleryHelper{
private Activity mActivity;
public GalleryHelper(Activity activity) {
mActivity = new WeakReference<>(activity).get();
}
}
第二步,创建文件夹实体类,代表文件夹数据。paths集合是文件夹下的所有路径。
public final class FolderEntity {
private int num;
private String name;
private List<String> paths = new ArrayList<>();
public int getNum() {
return paths.size();
}
public List<String> getPaths() {
return paths;
}
public void setName(String name) {
this.name = name;
}
}
第三步,首先获取手机所有的图片,在Activity里有getLoaderManager方法获取一个LoaderManager实例,该类用于异步加载手机内数据监测,这里不做多分析。我们调用它的initLoader方法,前两个参数这里不需要,只要实现LoaderCallbacks接口,并且指定Cursor类型。LoaderCallbacks接口有三个覆盖方法,我们需要用到的是onCreateLoader方法和onLoadFinished方法,前者是初始化Loader,后者是加载完成后的回调。
mActivity.getLoaderManager().initLoader(0, null, new LoaderManager.LoaderCallbacks<Cursor>() {
@Override
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
}
});
在onCreateLoader方法里,初始化CursorLoader,参数跟Cursor类下的query一样,第一个参数指定外部村粗多媒体URI;第二个参数是查找结果字段,这里只要了路径;第三个参数和第四个参数是搜索条件,条件为搜索jpeg格式和png格式,最后一个是按时间倒序搜索。
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
return new CursorLoader(mActivity,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
new String[]{MediaStore.Images.Media.DATA},
MediaStore.Images.Media.MIME_TYPE + "=? or "
+ MediaStore.Images.Media.MIME_TYPE + "=?",
new String[]{"image/jpeg", "image/png"},
MediaStore.Images.Media.DATE_ADDED + " DESC");
}
CursorLoader初始化完成之后,搜索的结果会回调在onLoadFinished方法。这时就可以处理搜索出来的图片路径。因为图片路径是没有分类,这里采用HashMap分类,以文件夹路径为key,具体文件夹FolderEntity类为value,如果当前图片路径的文件夹不存在则创建FolderEntity并且放入HashMap,存在则获取FolderEntity。
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
HashMap<String, FolderEntity> folderEntityHashMap = new HashMap<String, FolderEntity>();
if (cursor != null) {
while (cursor.moveToNext()) {
//图片路径
String path = cursor.getString(
cursor.getColumnIndex(MediaStore.Images.Media.DATA));
// 路径不存在或者文件不存在就跳过
File file = new File(path);
if (TextUtils.isEmpty(path) || !file.exists()) {
continue;
}
String folerPath = file.getParent();
FolderEntity folderEntity;
if (folderEntityHashMap.containsKey(folerPath)) {
folderEntity = folderEntityHashMap.get(folerPath);
} else {
folderEntity = new FolderEntity();
folderEntityHashMap.put(file.getParentFile().getName(), folderEntity);
}
folderEntity.getPaths().add(path);
}
cursor.close();
}
}
但是数据是要提供给外部的,HashMap就显得很麻烦,所以要转换ArrayList,并且按数量大小进行顺序。
private ArrayList<FolderEntity> map2List(HashMap<String, FolderEntity> mediaBeanMap) {
Iterator<FolderEntity> iterator = mediaBeanMap.values().iterator();
ArrayList<FolderEntity> list = new ArrayList<FolderEntity>();
while (iterator.hasNext()) {
list.add(iterator.next());
}
Collections.sort(list, new Comparator<FolderEntity>() {
@Override
public int compare(FolderEntity lhs, FolderEntity rhs) {
return lhs.getNum() > rhs.getNum() ? 1 : -1;
}
});
return list;
}
使用接口将数据提供给外部。
public interface GalleryCallback {
void complete(List<FolderEntity> list);
}
callback.complete(map2List(folderEntityHashMap));
第四步是实现拍照功能,这里实现是创建文件再启动拍照功能。
File imageStoreDir = new File(Environment.getExternalStorageDirectory(),
"/DCIM/" + mActivity.getResources().getString(R.string.app_name));
if (!imageStoreDir.exists()) {
imageStoreDir.mkdir();
}
Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (captureIntent.resolveActivity(mActivity.getPackageManager()) != null) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss", Locale.CHINA);
String filename = String.format("IMG%s", dateFormat.format(new Date()));
imagePath = new File(imageStoreDir, filename).getAbsolutePath();
captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(imagePath)));
mActivity.startActivityForResult(new Intent(
MediaStore.ACTION_IMAGE_CAPTURE), REQUEST_CODE);
}
定义回调接口,接收Activit的onActivityResult方法,表示回调成功把上面创建好的文件路径提供外部。
public interface CameraCallback {
void complete(String path);
}
public void onActivityResult(int requestCode, int resultCode) {
if (Activity.RESULT_OK == resultCode && REQUEST_CODE == requestCode) {
if (cameraCallback != null) {
cameraCallback.complete(imagePath);
}
}
}
外部调用
galleryHelper = new GalleryHelper(this);
galleryHelper.loadImages(new GalleryHelper.GalleryCallback() {
@Override
public void complete(List<FolderEntity> list) {
//加载本地图片返回结果
}
});
findViewById(R.id.btn_camera).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
galleryHelper.openCamera(new GalleryHelper.CameraCallback() {
@Override
public void complete(String path) {
//拍照返回结果
}
});
}
});
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
//使用拍照,必须接收Activity的onActivityResult方法
galleryHelper.onActivityResult(requestCode, resultCode);
}
别忘了加权限,这里为了简单实现,我把targetSdkVersion设置23以下,23和23以上的需要自行加上动态权限。
<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" /> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
整体就完成了,使用非常方便,有了这图库辅助器就可以自定义风格,再也不用受约束。网上大多开源图片选择器的搜索图片都是如此,但这例子难免有bug,不足之处望指教。
github地址:https://github.com/tanxinye/GalleryHelper
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
# Android
# 图库辅助器
# Android实现调用系统图库与相机设置头像并保存在本地及服务器
# Android编程实现调用系统图库与裁剪图片功能
# android图库竖屏不显示status bar的解决方法
# android图库播放幻灯片时按power键灭屏再亮屏显示keyguard
# 回调
# 不存在
# 太多
# 就可以
# 加载
# 提供给
# 自己的
# 的是
# 都是
# 第一个
# 不需要
# 网上
# 我把
# 也很
# 第二个
# 自定义
# 但这
# 各有
# 格格不入
# 别忘了
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
装修招标网站设计制作流程,装修招标流程?
Laravel怎么返回JSON格式数据_Laravel API资源Response响应格式化【技巧】
Laravel如何配置和使用队列处理异步任务_Laravel队列驱动与任务分发实例
Laravel的.env文件有什么用_Laravel环境变量配置与管理详解
JavaScript如何实现继承_有哪些常用方法
如何自定义safari浏览器工具栏?个性化设置safari浏览器界面教程【技巧】
如何在阿里云虚拟主机上快速搭建个人网站?
如何用AI一键生成爆款短视频文案?小红书AI文案写作指令【教程】
微信小程序 require机制详解及实例代码
html5的keygen标签为什么废弃_替代方案说明【解答】
JavaScript模板引擎Template.js使用详解
网易LOFTER官网链接 老福特网页版登录地址
Laravel DB事务怎么使用_Laravel数据库事务回滚操作
网站制作公司哪里好做,成都网站制作公司哪家做得比较好,更正规?
使用Dockerfile构建java web环境
C++用Dijkstra(迪杰斯特拉)算法求最短路径
C++时间戳转换成日期时间的步骤和示例代码
如何在万网开始建站?分步指南解析
如何在沈阳梯子盘古建站优化SEO排名与功能模块?
制作公司内部网站有哪些,内网如何建网站?
公司门户网站制作流程,华为官网怎么做?
java ZXing生成二维码及条码实例分享
手机怎么制作网站教程步骤,手机怎么做自己的网页链接?
制作企业网站建设方案,怎样建设一个公司网站?
Android okhttputils现在进度显示实例代码
图片制作网站免费软件,有没有免费的网站或软件可以将图片批量转为A4大小的pdf?
Laravel怎么为数据库表字段添加索引以优化查询
php485函数参数是什么意思_php485各参数详细说明【介绍】
教学论文网站制作软件有哪些,写论文用什么软件
?
Laravel中DTO是什么概念_在Laravel项目中使用数据传输对象(DTO)
HTML 中动态设置元素 name 属性的正确语法详解
html5源代码发行怎么设置权限_访问权限控制方法与实践【指南】
手机网站制作与建设方案,手机网站如何建设?
Python文件流缓冲机制_IO性能解析【教程】
Laravel广播系统如何实现实时通信_Laravel Reverb与WebSockets实战教程
javascript基于原型链的继承及call和apply函数用法分析
Laravel中间件如何使用_Laravel自定义中间件实现权限控制
青岛网站建设如何选择本地服务器?
Laravel事件监听器怎么写_Laravel Event和Listener使用教程
厦门模型网站设计制作公司,厦门航空飞机模型掉色怎么办?
HTML透明颜色代码在Angular里怎么设置_Angular透明颜色使用指南【详解】
java中使用zxing批量生成二维码立牌
Laravel如何记录日志_Laravel Logging系统配置与自定义日志通道
油猴 教程,油猴搜脚本为什么会网页无法显示?
如何快速搭建高效WAP手机网站?
Laravel怎么自定义错误页面_Laravel修改404和500页面模板
EditPlus中的正则表达式实战(5)
制作旅游网站html,怎样注册旅游网站?
如何确保西部建站助手FTP传输的安全性?
Laravel策略(Policy)如何控制权限_Laravel Gates与Policies实现用户授权

