时隔三个月,又来更新文章了。愿一切安好,奋力向前;
最近有一个选择手机本地视频和图片的需求,需要做一个自定义相册;
先看一下具体的效果:
类似于这种的效果。、
首先说一下这种排列效果就不多说了,网上一大堆,说多了也是没什么营养。一句话万能的
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,不同的适配器进行展示。核心的获取代码都已经贴出。如有疑问,欢迎私信你或留言。做一下记录,欢迎志同道合的朋友指导探讨。