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


    一、导入依赖

    api 'com.github.LuckSiege.PictureSelector:picture_library:v2.3.6'
    
    • 1

    二、自定义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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145

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

    效果:

    相册选择器选择单个图片

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

    //选择相册文件后显示在ivUpload控件上
    ImageView ivUpload = findViewById(R.id.img_upload)
    
    • 1
    • 2
    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();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    2、选择图片后回调

        @SuppressLint("MissingSuperCall")
        @Override
        public void onActivityResult(int requestCode, int resultCode, Intent data) {
            if (requestCode == FROM_ALBUM) {
                if (resultCode == Activity.RESULT_OK) {
                    String path;
                    List 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);
                    }
                }
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

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

    效果:

    相册选择器选择多个视频

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

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

    2、选择视频回调

        @SuppressLint("MissingSuperCall")
        @Override
        public void onActivityResult(int requestCode, int resultCode, Intent data) {
            switch (requestCode) {
                case FROM_ALBUM:
                    //选择相册文件后回调
                    if (resultCode == Activity.RESULT_OK) {
                        List 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;
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    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为null
    
            return  options.outWidth;
        }
        public int getHeight() {
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            BitmapFactory.decodeFile(filePath, options); // 此时返回的bitmap为null
    
            return  options.outHeight;
        }
    
        /*
        文件类型:视频8 音频9 图10
         */
        private int intFileType = -1;
        public void setIntFileType(int intFileType) {
            this.intFileType = intFileType;
        }
    
    	//......省略了一些getter和setter方法
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100

    拿到路径后填充自己的文件信息类对象

        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);   //设置文件类型是视频8
    
            return fileInfo;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

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

    	//是否是视频文件
        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;
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    视频文件的时长转换方法,转换后类似 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;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    三、本地视频文件的预览

    展示出来后点击可进行视频预览,根据路径预览本地视频文件可参考另一篇文章:Android之播放本地视频和Url视频方法

    四、完成,Nice!

  • 相关阅读:
    快手指纹之十八罗汉
    Java开发者的Python快速进修指南:实战之跳表pro版本
    阿里云oss(图片存储)--fastdfs (视频存储)
    实体和实体组的使用
    C++类和对象(四)—— 类常见题目详解
    5款免费的项目管理软件(推荐收藏)
    后端程序员实现一个IP归属地的小程序
    javaweb 之 JDBC 详解
    数据栅格化
    非线性最小二乘-高斯牛顿法
  • 原文地址:https://blog.csdn.net/qq_46269365/article/details/133942370