fbw315,超净工作台操作规程,梵希坨
前言
项目中经常要选择本地照片或者视频的需求,如果去扫描整个sd卡就太耗时间,其实android系统在启动时就已经把整个设备中的多媒体文件信息(文件名,类型,大小等)都存到了数据库,然后提供了contentprivider这个api来管理这个数据库,我们可以利用contentprivider来获取所有的照片和视频。
contentprivider初识
先看下管理的的数据库在哪
data/data/目录下:有很多这种文件夹(日历,联系人,下载管理,多媒体等)
我们需要的照片和视频就在media下面,进去看看。进去找到database然后打开external.db,就可以看到多张表(音频,文件,log,图像,视频等)
照片相册
那么获取照片直接通过 contentprovider读取images这个数据库就ok了,这里开启工作线程读取所有.jpeg和.png的图片,附上代码段:
/** * 读取手机中所有图片信息 */ private void getallphotoinfo() { new thread(new runnable() { @override public void run() { list<mediabean> mediabeen = new arraylist<>(); hashmap<string,list<mediabean>> allphotostemp = new hashmap<>();//所有照片 uri mimageuri = mediastore.images.media.external_content_uri; string[] projimage = { mediastore.images.media._id , mediastore.images.media.data ,mediastore.images.media.size ,mediastore.images.media.display_name}; cursor mcursor = getcontentresolver().query(mimageuri, projimage, mediastore.images.media.mime_type + "=? or " + mediastore.images.media.mime_type + "=?", new string[]{"image/jpeg", "image/png"}, mediastore.images.media.date_modified+" desc"); if(mcursor!=null){ while (mcursor.movetonext()) { // 获取图片的路径 string path = mcursor.getstring(mcursor.getcolumnindex(mediastore.images.media.data)); int size = mcursor.getint(mcursor.getcolumnindex(mediastore.images.media.size))/1024; string displayname = mcursor.getstring(mcursor.getcolumnindex(mediastore.images.media.display_name)); //用于展示相册初始化界面 mediabeen.add(new mediabean(mediabean.type.image,path,size,displayname)); // 获取该图片的父路径名 string dirpath = new file(path).getparentfile().getabsolutepath(); //存储对应关系 if (allphotostemp.containskey(dirpath)) { list<mediabean> data = allphotostemp.get(dirpath); data.add(new mediabean(mediabean.type.image,path,size,displayname)); continue; } else { list<mediabean> data = new arraylist<>(); data.add(new mediabean(mediabean.type.image,path,size,displayname)); allphotostemp.put(dirpath,data); } } mcursor.close(); } //更新界面 runonuithread(new runnable() { @override public void run() { //... } }); } }).start(); }
有四点需要注意:
视频相册
获取视频文件和上面基本一样,不过改下查询条件就行了,实际中有个问题:视频封面的获取。
首先视频封面缩略图在这个videothumbnails数据库,照片缩略图在thumbnails,对应到本地sd卡就是在sdcard/dcim/.thumbnails/文件夹(有的设备可能不同)
ps:这个文件夹是隐藏的,so你知道你的手机为何存储空间越来越小了吧,拍的照片缩略图全在这儿。。。非常非常多
实际中发现读取不到新录制的视频封面,需要手动调用一个方法,来生成这个封面然后才能在videothumbnails读取到:
参考:
//videoid是这个视频文件在数据库的id mediastore.video.thumbnails.getthumbnail(getcontentresolver(), videoid, mediastore.video.thumbnails.micro_kind, null);
并且这里封面和视频不在一个数据库,需要在两个cursor来读取
我这里获取整个sd的mp4格式视频,代码段如下:
/** * 获取手机中所有视频的信息 */ private void getallvideoinfos(){ new thread(new runnable() { @override public void run() { hashmap<string,list<mediabean>> allphotostemp = new hashmap<>();//所有照片 uri mimageuri = mediastore.video.media.external_content_uri; string[] proj = { mediastore.video.thumbnails._id , mediastore.video.thumbnails.data ,mediastore.video.media.duration ,mediastore.video.media.size ,mediastore.video.media.display_name ,mediastore.video.media.date_modified}; cursor mcursor = getcontentresolver().query(mimageuri, proj, mediastore.video.media.mime_type + "=?", new string[]{"video/mp4"}, mediastore.video.media.date_modified+" desc"); if(mcursor!=null){ while (mcursor.movetonext()) { // 获取视频的路径 int videoid = mcursor.getint(mcursor.getcolumnindex(mediastore.video.media._id)); string path = mcursor.getstring(mcursor.getcolumnindex(mediastore.video.media.data)); int duration = mcursor.getint(mcursor.getcolumnindex(mediastore.video.media.duration)); long size = mcursor.getlong(mcursor.getcolumnindex(mediastore.video.media.size))/1024; //单位kb if(size<0){ //某些设备获取size<0,直接计算 log.e("dml","this video size < 0 " + path); size = new file(path).length()/1024; } string displayname = mcursor.getstring(mcursor.getcolumnindex(mediastore.video.media.display_name)); long modifytime = mcursor.getlong(mcursor.getcolumnindex(mediastore.video.media.date_modified));//暂未用到 //提前生成缩略图,再获取:http://stackoverflow.com/questions/27903264/how-to-get-the-video-thumbnail-path-and-not-the-bitmap mediastore.video.thumbnails.getthumbnail(getcontentresolver(), videoid, mediastore.video.thumbnails.micro_kind, null); string[] projection = { mediastore.video.thumbnails._id, mediastore.video.thumbnails.data}; cursor cursor = getcontentresolver().query(mediastore.video.thumbnails.external_content_uri , projection , mediastore.video.thumbnails.video_id + "=?" , new string[]{videoid+""} , null); string thumbpath = ""; while (cursor.movetonext()){ thumbpath = cursor.getstring(cursor.getcolumnindex(mediastore.video.thumbnails.data)); } cursor.close(); // 获取该视频的父路径名 string dirpath = new file(path).getparentfile().getabsolutepath(); //存储对应关系 if (allphotostemp.containskey(dirpath)) { list<mediabean> data = allphotostemp.get(dirpath); data.add(new mediabean(mediabean.type.video,path,thumbpath,duration,size,displayname)); continue; } else { list<mediabean> data = new arraylist<>(); data.add(new mediabean(mediabean.type.video,path,thumbpath,duration,size,displayname)); allphotostemp.put(dirpath,data); } } mcursor.close(); } //更新界面 runonuithread(new runnable() { @override public void run() { //... } }); } }).start(); }
后记
其实android已经提供叫做cursorloader的api做这个事情,不需要手动new 工作线程,使用起来很简单有需要可以对上面代码改造。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。
如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复
Android studio 解决logcat无过滤工具栏的操作
Android Studio 恢复小窗口停靠模式(Docked Mode)
Android studio保存logcat日志到本地的操作
Android Studio快捷键生成TAG、Log.x日志输出介绍
网友评论