读取手机相册里的视频文件肯定是从数据库里面读取, 强大的MediaStore.Video 类里面有所有我们需要的信息,文件名称, 时长,类型, 大小等等, 我这里做了封装和展示, 分文件夹读取。
立竿见影上个效果图:
创建一个视频信息类
存储从数据库读取出来的视频信息
public class Video {
private int id;
private String title;
private String album;
private String artist;
private String displayName;
private String mimeType;
private String path;
private long size;
private long duration;
//缩略图
private Bitmap thumbnail;
}
提供一个获取所有视频信息的provider
public class VideoProvider implements AbstructProvider {
private Activity context;
public VideoProvider(Activity context) {
this.context = context;
}
@Override
public List<?> getList() {
List<Video> list = null;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inDither = false;
options.inPreferredConfig = Bitmap.Config.ALPHA_8;
ContentResolver contentResolver = context.getContentResolver();
if (context != null) {
Cursor cursor = contentResolver.query(
MediaStore.Video.Media.EXTERNAL_CONTENT_URI, null, null,
null, null);
if (cursor != null) {
list = new ArrayList<>();
while (cursor.moveToNext()) {
int id = cursor.getInt(cursor
.getColumnIndexOrThrow(MediaStore.Video.Media._ID));
String title = cursor
.getString(cursor
.getColumnIndexOrThrow(MediaStore.Video.Media.TITLE));
String album = cursor
.getString(cursor
.getColumnIndexOrThrow(MediaStore.Video.Media.ALBUM));
String artist = cursor
.getString(cursor
.getColumnIndexOrThrow(MediaStore.Video.Media.ARTIST));
String displayName = cursor
.getString(cursor
.getColumnIndexOrThrow(MediaStore.Video.Media.DISPLAY_NAME));
String mimeType = cursor
.getString(cursor
.getColumnIndexOrThrow(MediaStore.Video.Media.MIME_TYPE));
//视频路径
String path = cursor
.getString(cursor
.getColumnIndexOrThrow(MediaStore.Video.Media.DATA));
//视频时长
long duration = cursor
.getInt(cursor
.getColumnIndexOrThrow(MediaStore.Video.Media.DURATION));
long size = cursor
.getLong(cursor
.getColumnIndexOrThrow(MediaStore.Video.Media.SIZE));
Video video = new Video(id, title, album, artist, displayName, mimeType, path, size, duration);
list.add(video);
}
cursor.close();
}
}
return list;
}
}
这里主要需要视频路径还有时长用户展示。
在Activity里获取和展示
这里截取部分代码解释:
AbstructProvider provider = new VideoProvider(activity);
//获取所有数据
List<Video> list = (List<Video>) provider.getList();
List<Video> templist = new ArrayList<>();
AllList = new HashMap<>();
//我需要可以查看所有视频 所以加了这样一个文件夹名称
AllList.put(" " + getResources().getString(R.string.all_video), list);
//主要是读取文件夹的名称 做分文件夹的展示
for (Video video : list) {
String album = video.getAlbum();
if (TextUtils.isEmpty(album)) {
album = "Camera";
}
if (AllList.containsKey(album)) {
AllList.get(album).add(video);
} else {
templist = new ArrayList<>();
templist.add(video);
AllList.put(album, templist);
}
}
//在子线程读取好数据后使用handler 更新
if (list == null || list.size() == 0) {
Message message = new Message();
message.what = AppConstant.WHAT.FAILURE;
mHandler.sendMessage(message);
} else {
Message message = new Message();
message.what = AppConstant.WHAT.SUCCESS;
message.obj = list;
mHandler.sendMessage(message);
}
分文件夹展示效果:
遇到的问题
因为列表里面要显示视频缩略图,获取缩略图可以使用:
ThumbnailUtils方法是在android2.2(api8)之后新增的一个,该类为我们提供了三个静态方法供我们使用。
ThumbnailUtils.createVideoThumbnail(filePath, kind):
创建视频缩略图,filePath:文件路径,kind:MINI_KIND or MICRO_KIND
ThumbnailUtils.extractThumbnail(bitmap, width, height):
将bitmap裁剪为指定的大小
ThumbnailUtils.extractThumbnail(bitmap, width, height, options):将bitmap裁剪为指定的大小,可以有参数BitmapFactory.Options参数
但是以上获取视频缩略图的方法都是有一点耗时的, 大约600ms左右, 在查看秒拍快手等等获取视频的速度之后明白肯定没有这样获取, 但是我把秒拍和快手的数据缓存删除掉之后发现他们的第一次加载也是很慢的, 在经过了一番搜索和验证之后确定他们用的是缓存, 那我想到了能加载视频的框架 Glide 。
加载视频使用方式
Glide
.with(context)
.load(Uri.fromFile(new File(item.getPath())))
.asBitmap()
.into(simpleDraweeView);
到这为止从获取到显示都实现了。 源码上传到了github: