Android之自定义相册文件选择器

一、自定义FilePicker类

package com.custom.jfrb.util; //自己的包名位置import android.app.Activity;
import androidx.fragment.app.Fragment;import com.luck.picture.lib.PictureSelector;
import com.luck.picture.lib.config.PictureConfig;
import com.luck.picture.lib.config.PictureMimeType;public class FilePicker {public static final int FROM_ALBUM = 20001;public static final int TAKE_PICTURE = 20005;int selectionMode = PictureConfig.MULTIPLE;int mimeType = PictureMimeType.ofAll();int maxChoose = 20;boolean previewImage = true;boolean isCrop = false;boolean isCircleCrop = true;public boolean isShowCamera = false;int cropWidth;int cropHeight;Activity activity;Fragment fragment;public FilePicker(Activity activity) {this.activity = activity;}public FilePicker(Fragment fragment) {this.fragment = fragment;}public void start() {PictureSelector pictureSelector;if (activity != null) {pictureSelector = PictureSelector.create(activity);} else {pictureSelector = PictureSelector.create(fragment);}pictureSelector.openGallery(mimeType)//全部.PictureMimeType.ofAll()、图片.ofImage()、视频.ofVideo().loadImageEngine(GlideEngine.createGlideEngine()).maxSelectNum(maxChoose)// 最大图片选择数量 int.minSelectNum(1)// 最小选择数量 int.imageSpanCount(4)// 每行显示个数 int.selectionMode(selectionMode)// 多选 or 单选 PictureConfig.MULTIPLE or PictureConfig.SINGLE.previewImage(previewImage)// 是否可预览图片 true or false.previewVideo(false)// 是否可预览视频 true or false.enablePreviewAudio(false) // 是否可播放音频 true or false.isCamera(isShowCamera)// 是否显示拍照按钮 true or false.isZoomAnim(false)// 图片列表点击 缩放效果 默认true.sizeMultiplier(0.5f)// glide 加载图片大小 0~1之间 如设置 .glideOverride()无效.enableCrop(isCrop)// 是否裁剪 true or false.withAspectRatio(cropWidth, cropHeight).circleDimmedLayer(isCircleCrop).scaleEnabled(true).rotateEnabled(false) // 裁剪是否可旋转图片.compress(true)// 是否压缩 true or false.cropCompressQuality(80).isGif(false)// 是否显示gif图片 true or false.openClickSound(false)// 是否开启点击声音 true or false.forResult(FROM_ALBUM);//结果回调onActivityResult code}public void start(int requestId) {PictureSelector pictureSelector;if (activity != null) {pictureSelector = PictureSelector.create(activity);} else {pictureSelector = PictureSelector.create(fragment);}pictureSelector.openGallery(mimeType)//全部.PictureMimeType.ofAll()、图片.ofImage()、视频.ofVideo().maxSelectNum(20)// 最大图片选择数量 int.minSelectNum(1)// 最小选择数量 int.imageSpanCount(4)// 每行显示个数 int.selectionMode(selectionMode)// 多选 or 单选 PictureConfig.MULTIPLE or PictureConfig.SINGLE.previewImage(false)// 是否可预览图片 true or false.previewVideo(false)// 是否可预览视频 true or false.enablePreviewAudio(false) // 是否可播放音频 true or false.isCamera(false)// 是否显示拍照按钮 true or false.isZoomAnim(false)// 图片列表点击 缩放效果 默认true.sizeMultiplier(0.5f)// glide 加载图片大小 0~1之间 如设置 .glideOverride()无效.enableCrop(isCrop)// 是否裁剪 true or false.circleDimmedLayer(true).hideBottomControls(true).rotateEnabled(true) // 裁剪是否可旋转图片.compress(false)// 是否压缩 true or false.hideBottomControls(true)// 是否显示uCrop工具栏,默认不显示 true or false.isGif(false)// 是否显示gif图片 true or false.openClickSound(false)// 是否开启点击声音 true or false.forResult(requestId);//结果回调onActivityResult code}// 开启拍照public void startPicture() {PictureSelector pictureSelector;if (activity != null) {pictureSelector = PictureSelector.create(activity);} else {pictureSelector = PictureSelector.create(fragment);}pictureSelector.openCamera(PictureMimeType.ofImage()).enableCrop(isCrop)// 是否裁剪 true or false.circleDimmedLayer(isCrop).rotateEnabled(true) // 裁剪是否可旋转图片.forResult(TAKE_PICTURE);}public void setSelectionMode(int selectionMode) {this.selectionMode = selectionMode;}public void setMimeType(int mimeType) {this.mimeType = mimeType;}public void setMaxChoose(int maxChoose) {this.maxChoose = maxChoose;}public void setCrop(boolean isCrop) {this.isCrop = isCrop;}public void setCircleCrop(boolean isCircleCrop) {this.isCircleCrop = isCircleCrop;}public void setCropWidth(int cropWidth) {this.cropWidth = cropWidth;}public void setCropHeight(int cropHeight) {this.cropHeight = cropHeight;}public void setPreviewImage(boolean previewImage) {this.previewImage = previewImage;}
}

二、场景使用1(选择单个图片作为头像/封面等)

1、给某个控件添加监听,调用相册文件选择器

//选择相册文件后显示在ivUpload控件上
ImageView ivUpload = findViewById(R.id.img_upload)
FilePicker filePicker = new FilePicker(this);
filePicker.setMimeType(PictureMimeType.ofImage()); //选择类型是图片,只调出相册中所有图片文件
filePicker.setMaxChoose(1); //单次最多选择文件数量为1,可变
filePicker.setCrop(true);
filePicker.isShowCamera = true; //设置打开后有开始拍照项
filePicker.setCircleCrop(false);
filePicker.setCropWidth(ivUpload.getWidth()); 
filePicker.setCropHeight(ivUpload.getHeight());
filePicker.start();

2、选择图片后回调

    @SuppressLint("MissingSuperCall")@Overridepublic void onActivityResult(int requestCode, int resultCode, Intent data) {if (requestCode == FROM_ALBUM) {if (resultCode == Activity.RESULT_OK) {String path;List<LocalMedia> selectList = PictureSelector.obtainMultipleResult(data);if (selectList != null && !selectList.isEmpty()) {if (selectList.get(0).isCut()) {path = selectList.get(0).getCutPath();} else if (selectList.get(0).isCompressed()) {path = selectList.get(0).getCompressPath();} else {path = selectList.get(0).getPath();}   //加载选择的图片到控件中Glide.with(context).load(path).apply(options).into(ivUpload);}}}}

三、场景使用2(选择多个视频 /(图片)展示到页面上)

1、给某个控件添加监听,调用相册文件选择器

FilePicker filePicker = new FilePicker(this);
filePicker.setMimeType(PictureMimeType.ofVideo()); //设置选择类型为视频
filePicker.setMaxChoose(30); //设置单次选择最大数量为30个
filePicker.setSelectionMode(PictureConfig.MULTIPLE);
filePicker.start();

2、选择视频回调

    @SuppressLint("MissingSuperCall")@Overridepublic void onActivityResult(int requestCode, int resultCode, Intent data) {switch (requestCode) {case FROM_ALBUM://选择相册文件后回调if (resultCode == Activity.RESULT_OK) {List<LocalMedia> selectList = PictureSelector.obtainMultipleResult(data);if (selectList != null && selectList.size() > 0){int testCount = 0;String productPath = null;for (LocalMedia localMedia : selectList) {String path = localMedia.getPath();String TAG = "mylog_upload_file";Log.i(TAG, "压缩::" + localMedia.getCompressPath());Log.i(TAG, "原图::" + localMedia.getPath());Log.i(TAG, "裁剪::" + localMedia.getCutPath());Log.i(TAG, "是否开启原图::" + localMedia.isOriginal());Log.i(TAG, "原图路径::" + localMedia.getOriginalPath());Log.i(TAG, "Android Q 特有Path::" + localMedia.getAndroidQToPath());if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.Q) {// 这个设备的 Android 版本大于 Android Q// 在这里执行你的代码path = localMedia.getAndroidQToPath();} else if(localMedia.isOriginal()){Log.i(TAG, "原图路径::" + localMedia.getOriginalPath());path = localMedia.getOriginalPath();}else{path = localMedia.getCompressPath();}Log.d("mylog_upload_file","选择文件的路径是:"+ path);FileInfoStatus fileInfo = null;if(PublicUtils.isVideo(path)){fileInfo = getLocalFile(path);  //根据路径信息创建自己的JavaBean对象进行信息的展示,也可以创建List对象去存储,进而可以展示到recyclerview或其他布局中}else{RnToast.showToastLong(this,"只支持Mp3文件!");}}}}break;default:break;}}

FileInfoStatus为自己定义的文件信息类

package com.custom.jfrb.ui.fileTransfer.FileUploadUtils.bean;import android.graphics.BitmapFactory;import com.custom.jfrb.ui.fileTransfer.FileUploadUtils.base.DataTypeEnum;
import com.custom.jfrb.ui.fileTransfer.FileUploadUtils.db.DBHelper;
import com.custom.jfrb.ui.first.bean.MaterialDTO;
import com.custom.jfrb.util.PublicUtils;
import com.qukan.qkrecordupload.ConfigureManagerUtil;
import com.qukan.qkrecordupload.QkApplication;import java.io.File;
import java.io.Serializable;import static com.custom.jfrb.ui.fileTransfer.FileUploadUtils.base.DataTypeEnum.DISK;public class FileInfoStatus extends com.qukan.qkrecordupload.file.FileInfoStatus implements Serializable {public static final double GB = 1024.0 * 1024 * 1024;public static final double MB = 1024.0 * 1024;public static final double KB = 1024.0;protected String fileName;protected String timeLength;protected String filePath;protected String timeDate;protected String fileDisplayName;// 文件的大小protected String fileLength;public String getTimeLength(){return timeLength;}public long getFileTrueSize() {File temp = new File(filePath);if (!temp.isFile()){return 0;}// 获取文件的大小return temp.length();}public String getFileLength(){if("0".endsWith(fileLength)||"0B".endsWith(fileLength)){File temp = new File(filePath);long fileSize = temp.length();if (fileSize > GB){fileLength =  String.format("%.2fGB", fileSize / GB);}else if (fileSize > MB){fileLength = String.format("%.2fMB", fileSize / MB);}else if (fileSize > KB){fileLength = String.format("%.2fKB", fileSize / KB);}else{fileLength = String.format("%dB", fileSize);}if(!("0".endsWith(fileLength)||"0B".endsWith(fileLength))){DBHelper.instance().update(this);}}return fileLength;}public int getWidth() {BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = true;BitmapFactory.decodeFile(filePath, options); // 此时返回的bitmap为nullreturn  options.outWidth;}public int getHeight() {BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = true;BitmapFactory.decodeFile(filePath, options); // 此时返回的bitmap为nullreturn  options.outHeight;}/*文件类型:视频8 音频9 图10*/private int intFileType = -1;public void setIntFileType(int intFileType) {this.intFileType = intFileType;}//......省略了一些getter和setter方法}

拿到路径后创建自己的对象

    public static FileInfoStatus getLocalFile(String filePath) {File temp = new File(filePath);String pathFileName = temp.getName();L.d("pathFileName=%s", pathFileName);String[] arr = pathFileName.split("\\.");String pathHouzhui = arr[arr.length - 1]; //获取文件后缀if (!temp.isFile()) {return null;}FileInfoStatus fileInfo = new FileInfoStatus();fileInfo.setFilePath(temp.getPath());// 获取文件的大小long fileSize = temp.length();if (fileSize > GB) {fileInfo.setFileLength(String.format("%.2fGB", fileSize / GB));} else if (fileSize > MB) {fileInfo.setFileLength(String.format("%.2fMB", fileSize / MB));} else if (fileSize > KB) {fileInfo.setFileLength(String.format("%.2fKB", fileSize / KB));} else {fileInfo.setFileLength(String.format("%dB", fileSize));}// 设置日期和时长String timeDate = formatter.format(new Date(System.currentTimeMillis()));fileInfo.setTimeDate(timeDate);MediaMetadataRetriever mmr = new MediaMetadataRetriever();mmr.setDataSource(filePath);String duration = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);fileInfo.setTimeLength(PublicUtils.msToHms(Long.parseLong(duration)));String newFileName = getTimeAndRandom();String uploadFilename = newFileName + "_upload0." + pathHouzhui;fileInfo.setFileDisplayName(pathFileName);fileInfo.setFileName(newFileName + "_" + 0 + "." + pathHouzhui);file.setIntFileType(8);   //设置文件类型是视频8return fileInfo;}

//几个判断文件类型的方法

	//是否是视频文件public static boolean isVideo(String path) {if (path.endsWith("mp4") || path.endsWith("MP4")) {return true;} else {return false;}}//是否是图片文件public static boolean isImage(String path) {if (path.endsWith("jpg") || path.endsWith("JPG") || path.endsWith("png") || path.endsWith("PNG")|| path.endsWith("jpeg")|| path.endsWith("JPEG")) {return true;} else {return false;}}//是否是音频文件public static boolean isAudio(String path) {if (path.endsWith("mp3") || path.endsWith("MP3") ) {return true;} else {return false;}}

视频文件转换方法 类似 00:00:00

public static String msToHms(long milliSecondTime) {int hour = (int) milliSecondTime / (60 * 60 * 1000);int minute = (int) (milliSecondTime - hour * 60 * 60 * 1000) / (60 * 1000);int seconds = (int) (milliSecondTime - hour * 60 * 60 * 1000 - minute * 60 * 1000) / 1000;if (seconds >= 60) {seconds = seconds % 60;minute += seconds / 60;}if (minute >= 60) {minute = minute % 60;hour += minute / 60;}String sh = "";String sm = "";String ss = "";if (hour < 10) {sh = "0" + String.valueOf(hour);} else {sh = String.valueOf(hour);}if (minute < 10) {sm = "0" + String.valueOf(minute);} else {sm = String.valueOf(minute);}if (seconds < 10) {ss = "0" + String.valueOf(seconds);} else {ss = String.valueOf(seconds);}return sh + ":" + sm + ":" + ss;}

三、完成、Nice!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/111622.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在mysql8查询中使用ORDER BY结合LIMIT时,分页查询时出现后一页的数据重复前一页的部分数据。

这里写目录标题 问题描述&#xff1a;问题模拟&#xff1a;原因分析问题解释问题解决验证官方文档支持 问题描述&#xff1a; 在mysql8查询中使用ORDER BY结合LIMIT时&#xff0c;分页查询时出现后一页的数据重复前一页的部分数据。 问题模拟&#xff1a; 表table_lock_test&…

pytorch里面的 nn.Parameter 和 tensor有哪些异同点

简单来说&#xff0c;你可以把tensor看作是一个通用的数据结构&#xff0c;而nn.Parameter看作是一种特殊的tensor&#xff0c;这种tensor可以被优化以提高模型的性能。在创建模型参数时&#xff0c;你应该使用nn.Parameter而不是直接使用tensor&#xff0c;因为这样可以确保模…

Milvus 介绍

Milvus 介绍 Milvus 矢量数据库是什么&#xff1f;关键概念非结构化数据嵌入向量向量相似度搜索 为什么是 Milvus?支持哪些索引和指标&#xff1f;索引类型相似度指标(Similarity metrics) 应用示例Milvus 是如何设计的&#xff1f;开发者工具API访问Milvus 生态系统工具 本页…

《数据结构、算法与应用C++语言描述》使用C++语言实现数组双端队列

《数据结构、算法与应用C语言描述》使用C语言实现数组双端队列 定义 队列的定义 队列&#xff08;queue&#xff09;是一个线性表&#xff0c;其插入和删除操作分别在表的不同端进行。插入元素的那一端称为队尾&#xff08;back或rear&#xff09;&#xff0c;删除元素的那一…

【vue】el-carousel实现视频自动播放与自动切换到下一个视频功能:

文章目录 一、原因:二、实现代码:三、遇到的问题&#xff1a;【1】问题&#xff1a;el-carousel页面的视频不更新【2】问题&#xff1a;多按几次左按钮&#xff0c;其中跳过没有播放的视频没有销毁&#xff0c;造成再次自动播放时会跳页 一、原因: 由于后端无法实现将多条视频拼…

手机爬虫用Scrapy详细教程:构建高效的网络爬虫

如果你正在进行手机爬虫的工作&#xff0c;并且希望通过一个高效而灵活的框架来进行数据抓取&#xff0c;那么Scrapy将会是你的理想选择。Scrapy是一个强大的Python框架&#xff0c;专门用于构建网络爬虫。今天&#xff0c;我将与大家分享一份关于使用Scrapy进行手机爬虫的详细…

照片后期编辑工具Lightroom Classic 2024 mac中文新增功能

Lightroom Classic 2024&#xff08;lrC2024&#xff09;是专为摄影爱好者和专业摄影师设计的软件&#xff0c;它提供了全面的照片编辑工具&#xff0c;可以精准调整照片的色彩、对比度和曝光等参数&#xff0c;以便定制后期处理效果。 在lrC2024中&#xff0c;用户体验得到了提…

文件的逻辑结构(顺序文件,索引文件)

所谓的“逻辑结构”&#xff0c;就是指在用户看来&#xff0c;文件内部的数据应该是如何组织起来的。 而“物理结构”指的是在操作系统看来&#xff0c;文件的数据是如何存放在外存中的。 1.无结构文件 无结构文件:文件内部的数据就是一系列二进制流或字符流组成。无明显的逻…

SortedSet 和 List 异同点

SortedSet 在 Java 的整个集合体系中&#xff0c;集合可以分成两个体系&#xff0c;一个是 Collection 存储单个对象的集合&#xff0c;另一个是 k-v 结构的 Map 集合。 SortedSet 是 Collection 体系下 Set 接口下的派生类&#xff0c;而 Set 集合的特征是不包含重 复的元素的…

Linux screen命令解决SSH远程服务器训练代码断开连接后运行中断

Linux screen命令解决SSH远程服务器训练代码断开连接后运行中断_linux screen ssh-CSDN博客 xshell远程连接服务器&#xff0c;screen指令进行后台任务运行_xshell创建screen-CSDN博客

pytest合集(11)— conftest.py文件

1、conftest.py文件 conftest.py文件是pytest框架中的一个特殊文件&#xff0c;用于定义共享的设置、夹具(fixture)和钩子函数&#xff08;hook&#xff09;。 在pytest中&#xff0c;conftest.py文件可以用于在整个测试项目中共享夹具、配置和钩子函数。通过在conftest.py文…

(论文翻译)UFO: Unified Feature Optimization——UFO:统一特性优化

作者&#xff1a; Teng Xi 论文总结&#xff1a;总结 Code: https://github.com/PaddlePaddle/VIMER/tree/main/UFO 摘要&#xff1a; 本文提出了一种新的统一特征优化(Unified Feature Optimization, UFO)范式&#xff0c;用于在现实世界和大规模场景下训练和部署深度模型…

迭代器-面试

迭代器-面试 Object.prototype[Symbol.iterator] function () {return Object.values(this)[Symbol.iterator](); };var [a, b] { a: 1, b: 2 };console.log(a, b);解释 Object.prototype[Symbol.iterator] function () {return Object.values(this)[Symbol.iterator](); …

新媒体运营的营销方案

一、目标客户群体 新媒体运营是通过社交媒体、短视频、直播等方式将信息快速传播出去&#xff0c;因此&#xff0c;适合的目标客户群体应该是年轻人群体&#xff0c;包括大学生、职场青年、年轻家庭等。 二、营销策略 1、社交媒体营销策略 借助社交媒体平台&#xff0c;建立企…

asp.net特色商品购物网站系统VS开发sqlserver数据库web结构c#编程Microsoft Visual Studio

一、源码特点 asp.net特色商品购物网站系统 是一套完善的web设计管理系统&#xff0c;系统采用mvc模式&#xff08;BLLDALENTITY&#xff09;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为 vs2010&#xff0c;数据库为sqlserver2008&a…

安装Apache2.4

二、安装配置Apache&#xff1a; 中文官网&#xff1a;Apache 中文网 官网 (p2hp.com) 我下的是图中那个版本&#xff0c;最新的64位 下载下后解压缩。如解压到D:\tool\Apache24 PS&#xff1a;特别要注意使用的场景和64位还是32位版本 2、修改Apcahe配置文件 具体步骤: 打…

利用ZipInputStream(解压)/ZipOutputStream(压缩)文件夹

在操作.zip的压缩包时&#xff0c;可以用到高级流ZipInputStream和ZipOutputStream。.zip文件中的每个文件夹和文件都是一个ZipEntry对象。解压和压缩的本质就是操作每个ZipEntry对象&#xff0c;只能操作后缀为.zip的文件 1 解压.zip文件 ZipInputStream&#xff0c;解压。是…

Required MultipartFile parameter ‘file‘ is not present

出现这个原因我们首先想到的是加一个RequestParam("file")&#xff0c;但是还有可能的原因是因为我们的名字有错误 <span class"input-group-addon must">模板上传 </span> <input id"uploadFileUpdate" name"importFileU…

内衣专用洗衣机怎么样?选购内衣裤洗衣机的方法

有的小伙伴在问内衣洗衣机有没有必要入手&#xff0c;答案是有必要的&#xff0c;贴身衣物一定要和普通衣服分开来洗&#xff0c;而且用手来清洗衣物真的很耗时间而且还清洗不干净&#xff0c;有了内衣洗衣机&#xff0c;我们不仅可以解放双手&#xff0c;在清洗过程中还能更加…

安装Python没有pip python3.8为啥没安装pip

以管理员打开&#xff0c;很&#xff01;重&#xff01;要&#xff01; 进入存储路径: (获取存储路径的方法&#xff1a;在python中 import sys sys.path ) 1,cd C:\Python38\Scripts\dist\pip-23.3 python下安装pip: python setup.py install 回车后&#xff0c;安装开始运行…