自定义相册并获取手机媒体库中视频文件和图片文件

时隔三个月,又来更新文章了。愿一切安好,奋力向前;

最近有一个选择手机本地视频和图片的需求,需要做一个自定义相册;

先看一下具体的效果:


photo.png

类似于这种的效果。、

首先说一下这种排列效果就不多说了,网上一大堆,说多了也是没什么营养。一句话万能的

RecyclerView,不明白的自己去找好了。

本文重点是放在查询设备中的图片和视频文件并获取视频的缩略图。

思路:这两中情况归结到底就是一种情况,那就是获取本地文件并展示。只不过是文件格式不同,后期处理不同。

1、获取读取手机文件的对应权限(就是读写权限)

2、查询你想要的格式的文件,例如图片jpg,png,jpeg/视频mp4,3gp.aiv,rmvb等

思路很简单,重点再视频缩略图的处理。下面会说到。

一、获取图片文件

代码
...
/**

  • 获取图片的路径
    */

    private void getPhotoFile() {
    if (!Environment.getExternalStorageState().equals(
    Environment.MEDIA_MOUNTED)) {
    showToast("检测到没有内存卡");
    return;
    }
    new Thread(new Runnable() {
    @Override
    public void run() {
    // 根据图片文件格式进行数据库查询
    Uri mImageUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
    ContentResolver mContentResolver = PhotoAlbumActivity.this.getContentResolver();
    Cursor mCursor = mContentResolver.query(mImageUri, null,
    MediaStore.Images.Media.MIME_TYPE + "=? or "+
    MediaStore.Images.Media.MIME_TYPE + "=? or "+
    MediaStore.Images.Media.MIME_TYPE + "=?",
    new String[]{"image/jpeg", "image/png","image/jpg"},
    MediaStore.Images.Media.DATE_TAKEN +" DESC");

             while (mCursor.moveToNext()) {
                 String path = mCursor.getString(mCursor.getColumnIndex(MediaStore.Images.Media.DATA));// 1.获取图片的路径
                 File parentFile = new File(path).getParentFile();
                 if (parentFile == null)
                     continue;//不获取sd卡根目录下的图片
                 mDirPaths.add(path);
             }
             mCursor.close();
             mHandler.sendEmptyMessage(1);
         }
     }).start();
    

    }

Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
setPhotoAdapterData();//设置图片的显示
}
};

//设置适配器数据
private void setPhotoAdapterData() {
GridLayoutManager manager = new GridLayoutManager(this, 3);
photo_list.setLayoutManager(manager);
PhotoListAdater adater = new PhotoListAdater(mDirPaths, this);
photo_list.setAdapter(adater);
adater.setPhotoOnClicklisenter(new PhotoListAdater.PhotoOnClicklisenter() {
@Override
public void choosePhoto(List<String> path) {
if (path != null) {
chooseDate.addAll(path);
}
}

        @Override
        public void hintUser() {
            Toast.makeText(mContext, "最多添加3张图片", Toast.LENGTH_SHORT).show();
        }
    });
}

...
2、获取视频文件
...
/**
* 获取本地所有的视频
*
* @return list 查询到的视频实体集合
*/

public static List<VedioBean> getAllLocalVideos(Context context) {
    String[] projection = {

            MediaStore.Video.Media.DATA,

            MediaStore.Video.Media.DISPLAY_NAME,

            MediaStore.Video.Media.DURATION,

            MediaStore.Video.Media.SIZE

    };

    /**
     * 根据视频文件格式 进行数据库查询
     */

    String where = MediaStore.Images.Media.MIME_TYPE + "=? or "

            + MediaStore.Video.Media.MIME_TYPE + "=? or "

            + MediaStore.Video.Media.MIME_TYPE + "=? or "

            + MediaStore.Video.Media.MIME_TYPE + "=? or "

            + MediaStore.Video.Media.MIME_TYPE + "=? or "

            + MediaStore.Video.Media.MIME_TYPE + "=? or "

            + MediaStore.Video.Media.MIME_TYPE + "=? or "

            + MediaStore.Video.Media.MIME_TYPE + "=? or "

            + MediaStore.Video.Media.MIME_TYPE + "=?";

    String[] whereArgs = {"video/mp4", "video/3gp", "video/aiv", "video/rmvb", "video/vob", "video/flv",

            "video/mkv", "video/mov", "video/mpg"};

    List<VedioBean> list = new ArrayList<>();

    Cursor cursor = context.getContentResolver().query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI,

            projection, where, whereArgs, MediaStore.Video.Media.DATE_ADDED + " DESC ");

    if (cursor == null) {

        return list;

    }

    try {

        while (cursor.moveToNext()) {

            long size = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.SIZE)); // 大小
            /**
             * 过滤文件大小
             */
            if (size < 600 * 1024 * 1024) {

                VedioBean vedioBean = new VedioBean();

                String path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA)); // 路径

                long duration = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATION)); // 时长
                /**
                 * 设置视频实体属性
                 */
                vedioBean.setTitle(cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.DISPLAY_NAME)));
                vedioBean.setLogo(path);
                vedioBean.setFilePath(path);
                vedioBean.setChecked(false);
                vedioBean.setFileType(2);
                vedioBean.setUploadedSize(0);
                vedioBean.setTimeStamps(System.currentTimeMillis() + "");
                SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
                format.setTimeZone(TimeZone.getTimeZone("GMT+0"));
                String t = format.format(duration);
                vedioBean.setTime(t);
                vedioBean.setFileSize(size);
                list.add(vedioBean);

            }

        }

    } catch (Exception e) {

        e.printStackTrace();

    } finally {

        cursor.close();

    }

    return list;

}

/**
* 获取视频的缩略图
* @param videoPath
* @param width
* @param height
* @param kind
* @return
*/
public static Bitmap getVideoThumbnail(String videoPath, int width, int height, int kind) {
Bitmap bitmap = null;
// 获取视频的缩略图
bitmap = ThumbnailUtils.createVideoThumbnail(videoPath, kind);
if(bitmap!= null){
bitmap = ThumbnailUtils.extractThumbnail(bitmap, width, height,
ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
}
return bitmap;
}

/**
* 视频集合
*/
private List<Bitmap> vedioDate = new ArrayList<>();

/**
 * 展示视频文件列表
 */
private void showVedioFile() {
    List<VedioBean> videos = getAllLocalVideos(this);
    for (int i = 0; i < videos.size(); i++) {
        vedioDate.add(getVideoThumbnail(videos.get(i).getFilePath(),800,800,1));
    }
    GridLayoutManager manager = new GridLayoutManager(this, 3);
    VedioListAdapter adapter = new VedioListAdapter(this, vedioDate);
    photo_list.setLayoutManager(manager);
    photo_list.setAdapter(adapter);

}

// 请求权限 并根据类型 获取对应的文件
PermissionUtils.requestPermission(this,PermissionUtils.CODE_READ_EXTERNAL_STORAGE,requestCode -> {
if (type == TYPE_PHOTO) {
getPhotoFile();
}else {
showVedioFile();
}

    });

...
使用的同一个RecyclerView,不同的适配器进行展示。核心的获取代码都已经贴出。如有疑问,欢迎私信你或留言。做一下记录,欢迎志同道合的朋友指导探讨。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345