Android之MediaStore

在日常开发中,我们经常会使用MediaStore来获取手机的音频、图片、视频等相关信息。下面3个是常见的内部类:

MediaStore.Audio获取音频信息的类

MediaStore.Images获取图片信息

MediaStore.Video获取视频信息

1、MediaStore.Audio

在这个类中我们可以获取音频的专辑、艺术家、流派等等,通过 MediaStore.Audio.AlbumColumns 可以查阅专辑表的字段信息,我们也可以通过Uri来查询手机上的

专辑表的字段信息。主要是用 MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI 的Uri来查询。其中EXTERNAL_CONTENT_URI 为查询外置内存卡的,内置内存卡

为 INTERNAL_CONTENT_URI。
[java] view plain copy

private Uri albumUri = MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI;  

[java] view plain copy

// 配置<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>权限  
    private void getUriColumns(Uri uri){  
        Cursor cursor = getContentResolver().query(uri, null, null, null, null);  
        cursor.moveToFirst();   
        String[] columns = cursor.getColumnNames();  
        for (String string : columns) {  
            System.out.println(cursor.getColumnIndex(string)+" = "+string);  
        }  
    }  

结果为:

06-24 01:05:44.979: I/System.out(1529): 0 = _id
06-24 01:05:44.983: I/System.out(1529): 1 = album
06-24 01:05:44.987: I/System.out(1529): 2 = album_key
06-24 01:05:44.987: I/System.out(1529): 3 = minyear
06-24 01:05:44.987: I/System.out(1529): 4 = maxyear
06-24 01:05:44.987: I/System.out(1529): 5 = artist
06-24 01:05:44.987: I/System.out(1529): 6 = artist_id
06-24 01:05:44.987: I/System.out(1529): 7 = artist_key
06-24 01:05:44.987: I/System.out(1529): 8 = numsongs
06-24 01:05:44.987: I/System.out(1529): 9 = album_art

可以看到相应的字段和下标是什么。

[java] view plain copy

// 艺术家  
    private Uri artUri = MediaStore.Audio.Artists.EXTERNAL_CONTENT_URI;  
    // 流派  
    private Uri genresUri = MediaStore.Audio.Genres.EXTERNAL_CONTENT_URI;  

也可以通过上面的Uri来查询音频的艺术家和流派相应的信息。

音频信息比较全的是这个类 MediaStore.Audio.Media 可以通过Uri来看下字段有什么:
[java] view plain copy

private Uri mediaUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;  

字段为:

06-24 01:25:51.656: I/System.out(5292): 0 = _id
06-24 01:25:51.656: I/System.out(5292): 1 = _data 音频路径
06-24 01:25:51.656: I/System.out(5292): 2 = _display_name音频名称包括后缀名
06-24 01:25:51.656: I/System.out(5292): 3 = _size 音频大小
06-24 01:25:51.656: I/System.out(5292): 4 = mime_type音频类型
06-24 01:25:51.656: I/System.out(5292): 5 = date_added
06-24 01:25:51.656: I/System.out(5292): 6 = is_drm
06-24 01:25:51.656: I/System.out(5292): 7 = date_modified
06-24 01:25:51.656: I/System.out(5292): 8 = title 音频名称不包括后缀名
06-24 01:25:51.656: I/System.out(5292): 9 = title_key
06-24 01:25:51.664: I/System.out(5292): 10 = duration音频时长
06-24 01:25:51.664: I/System.out(5292): 11 = artist_id
06-24 01:25:51.664: I/System.out(5292): 12 = composer
06-24 01:25:51.664: I/System.out(5292): 13 = album_id
06-24 01:25:51.672: I/System.out(5292): 14 = track
06-24 01:25:51.672: I/System.out(5292): 15 = year
06-24 01:25:51.672: I/System.out(5292): 16 = is_ringtone
06-24 01:25:51.672: I/System.out(5292): 17 = is_music
06-24 01:25:51.672: I/System.out(5292): 18 = is_alarm
06-24 01:25:51.672: I/System.out(5292): 19 = is_notification
06-24 01:25:51.672: I/System.out(5292): 20 = is_podcast
06-24 01:25:51.672: I/System.out(5292): 21 = bookmark
06-24 01:25:51.700: I/System.out(5292): 22 = album_artist
06-24 01:25:51.700: I/System.out(5292): 23 = artist_id:1
06-24 01:25:51.700: I/System.out(5292): 24 = artist_key
06-24 01:25:51.700: I/System.out(5292): 25 = artist
06-24 01:25:51.700: I/System.out(5292): 26 = album_id:1
06-24 01:25:51.700: I/System.out(5292): 27 = album_key
06-24 01:25:51.700: I/System.out(5292): 28 = album

字段很多,就对比较常用的注释了下,有字段是和其他表关联的如 artist_id、album_id等等,其中比较常用的是 _data、 _display_name、 _size、mime_type、 title、duration等字段

可以通过常用的字段来查询手机下相应的音频文件:
[java] view plain copy

private Uri mediaUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;  

[java] view plain copy

private void getUriData(Uri uri){  

        String[] projection = {"_data","_display_name","_size","mime_type","title","duration"};  
        Cursor cursor = getContentResolver().query(uri, projection, null, null, null);  
        cursor.moveToFirst();  
        do {  
            System.out.println("_data = "+cursor.getString(cursor.getColumnIndex("_data")));  
            System.out.println("_display_name = "+cursor.getString(cursor.getColumnIndex("_display_name")));  
            System.out.println("_size = "+cursor.getString(cursor.getColumnIndex("_size")));  
            System.out.println("mime_type = "+cursor.getString(cursor.getColumnIndex("mime_type")));  
            System.out.println("title = "+cursor.getString(cursor.getColumnIndex("title")));  
            System.out.println("duration = "+cursor.getString(cursor.getColumnIndex("duration")));  
        } while (cursor.moveToNext());  
    }  

结果如下:

06-24 13:40:12.445: I/System.out(4610): _data = /mnt/sdcard/kgmusic/download/孙楠、神话、韩红 - 美丽的神话.mp3
06-24 13:40:12.445: I/System.out(4610): _display_name = 孙楠、神话、韩红 - 美丽的神话.mp3
06-24 13:40:12.445: I/System.out(4610): _size = 4635648
06-24 13:40:12.445: I/System.out(4610): mime_type = audio/mpeg
06-24 13:40:12.445: I/System.out(4610): title = 美丽的神话
06-24 13:40:12.445: I/System.out(4610): duration = 289712

06-24 13:40:12.445: I/System.out(4610): _data = /mnt/sdcard/kgmusic/download/那英、孙楠 - 只要有你.mp3
06-24 13:40:12.445: I/System.out(4610): _display_name = 那英、孙楠 - 只要有你.mp3
06-24 13:40:12.445: I/System.out(4610): _size = 4012536
06-24 13:40:12.445: I/System.out(4610): mime_type = audio/mpeg
06-24 13:40:12.445: I/System.out(4610): title = 只要有你( 少年包青天 片尾曲)
06-24 13:40:12.446: I/System.out(4610): duration = 250784

由于音频过多就列举了两个,可以看到通过字段的查询获取到音频的详细信息。

2、MediaStore.Images

在该类中有一个借口和两个class ,分别为:

MediaStore.Images.ImageColumns可以查看图片的字段信息

MediaStore.Images.Media可以获取图片的相关信息

MediaStore.Images.Thumbnails可以获取图片的缩略图

关于MediaStore.Images.ImageColumns 可以查看api ,下面通过MediaStore.Images.Media 查询手机上的图片。
[java] view plain copy

private Uri imageUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;  

通过上面查看字段的代码,可以看到如下图片的字段信息:

06-24 13:52:34.018: I/System.out(4755): 0 = _id
06-24 13:52:34.018: I/System.out(4755): 1 = _data
06-24 13:52:34.018: I/System.out(4755): 2 = _size
06-24 13:52:34.018: I/System.out(4755): 3 = _display_name
06-24 13:52:34.018: I/System.out(4755): 4 = mime_type
06-24 13:52:34.018: I/System.out(4755): 5 = title
06-24 13:52:34.018: I/System.out(4755): 6 = date_added
06-24 13:52:34.018: I/System.out(4755): 7 = date_modified
06-24 13:52:34.018: I/System.out(4755): 8 = description
06-24 13:52:34.018: I/System.out(4755): 9 = picasa_id
06-24 13:52:34.018: I/System.out(4755): 10 = isprivate
06-24 13:52:34.018: I/System.out(4755): 11 = latitude
06-24 13:52:34.018: I/System.out(4755): 12 = longitude
06-24 13:52:34.018: I/System.out(4755): 13 = datetaken
06-24 13:52:34.018: I/System.out(4755): 14 = orientation
06-24 13:52:34.018: I/System.out(4755): 15 = mini_thumb_magic
06-24 13:52:34.018: I/System.out(4755): 16 = bucket_id
06-24 13:52:34.018: I/System.out(4755): 17 = bucket_display_name
06-24 13:52:34.018: I/System.out(4755): 18 = is_drm
06-24 13:52:34.018: I/System.out(4755): 19 = drm_content_uri
06-24 13:52:34.018: I/System.out(4755): 20 = drm_offset
06-24 13:52:34.018: I/System.out(4755): 21 = drm_dataLen
06-24 13:52:34.018: I/System.out(4755): 22 = drm_rights_issuer
06-24 13:52:34.018: I/System.out(4755): 23 = drm_content_name
06-24 13:52:34.018: I/System.out(4755): 24 = drm_content_description
06-24 13:52:34.018: I/System.out(4755): 25 = drm_content_vendor
06-24 13:52:34.019: I/System.out(4755): 26 = drm_icon_uri
06-24 13:52:34.019: I/System.out(4755): 27 = drm_method

可以查看和音频的字段是有些不同的。获取图片的基本信息:
[java] view plain copy

 private void getUriData(Uri uri){  

    String[] projection = {"_data","_display_name","_size","mime_type","title","orientation"};  
    Cursor cursor = getContentResolver().query(uri, projection, null, null, null);  
    cursor.moveToFirst();  
    do {  
System.out.println("_data = "+cursor.getString(cursor.getColumnIndex("_data")));  
System.out.println("_display_name = "+cursor.getString(cursor.getColumnIndex("_display_name")));  
System.out.println("_size = "+cursor.getString(cursor.getColumnIndex("_size")));  
System.out.println("mime_type = "+cursor.getString(cursor.getColumnIndex("mime_type")));  
System.out.println("title = "+cursor.getString(cursor.getColumnIndex("title")));  
System.out.println("orientation = "+cursor.getString(cursor.getColumnIndex("orientation")));  
 while (cursor.moveToNext());  
 }<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"> </span>  

orientation 为图片的对其方式, 输出信息为:

06-24 13:57:59.653: I/System.out(4851): _data = /mnt/sdcard/sdcard2/Photo/IMG_20100101_081333.jpg
06-24 13:57:59.653: I/System.out(4851): _display_name = IMG_20100101_081333.jpg
06-24 13:57:59.653: I/System.out(4851): _size = 795457
06-24 13:57:59.653: I/System.out(4851): mime_type = image/jpeg
06-24 13:57:59.653: I/System.out(4851): title = IMG_20100101_081333
06-24 13:57:59.654: I/System.out(4851): orientation = 90

06-24 13:57:59.654: I/System.out(4851): _data = /mnt/sdcard/sdcard2/Photo/IMG_20100101_081344.jpg
06-24 13:57:59.654: I/System.out(4851): _display_name = IMG_20100101_081344.jpg
06-24 13:57:59.654: I/System.out(4851): _size = 673729
06-24 13:57:59.654: I/System.out(4851): mime_type = image/jpeg
06-24 13:57:59.654: I/System.out(4851): title = IMG_20100101_081344
06-24 13:57:59.654: I/System.out(4851): orientation = 90

06-24 13:57:59.654: I/System.out(4851): _data = /mnt/sdcard/QQ_Screenshot/1425453607656.png
06-24 13:57:59.654: I/System.out(4851): _display_name = 1425453607656.png
06-24 13:57:59.654: I/System.out(4851): _size = 65742
06-24 13:57:59.654: I/System.out(4851): mime_type = image/png
06-24 13:57:59.654: I/System.out(4851): title = 1425453607656
06-24 13:57:59.654: I/System.out(4851): orientation = null

MediaStore.Images.Thumbnails获取缩略图这个类和下面获取手机视频信息一起讲。

2、MediaStore.Video

该类有两个class比较常用:MediaStore.Video.Media MediaStore.Video.Thumbnails 一个是获取视频的相关信息,一个是获取视频的缩略图

MediaStore.Video.Media 用法和上面介绍的一样,不清楚它有什么字段的,可以先查询出来,再来获取视频的相关信息,和路径、名称、类型等等,这里就不介绍了。下面是获取视频的缩略图的相关操作。

MediaStore.Video.Thumbnails 主要用到这个两个方法:
[java] view plain copy

static Bitmap  getThumbnail(ContentResolver cr, long origId, long groupId, int kind, BitmapFactory.Options options)    

[java] view plain copy

static Bitmap  getThumbnail(ContentResolver cr, long origId, int kind, BitmapFactory.Options options)    

这里第一个参数可以通过 getContentResolver() 来获取 、第二个参数 origId 为视频的ID ,第三个参数 groupId 我也不太清楚,大家知道的可以告诉我一下O(∩_∩)O, 第四个参数kind 有两种类型分别为:
MICRO_KIND(微型分辨率小)MINI_KIND (迷你型)、第五个参数 为BitmapFactory.Option对象

<1> 第一种是使用上面介绍的方法:
[java] view plain copy

public class ThumbnailActivity extends Activity {  

    private ListView listView;  

    private Uri videoUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;  

    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.video_listview);  

        listView = (ListView) findViewById(R.id.mylistview1);  
        new MyThumbnailAsyncTask().execute(videoUri);  

    }  

    /** 
     * 异步加载 
     * 
     */  
    private class MyThumbnailAsyncTask extends AsyncTask<Uri, Void, List<Bitmap>>{  

        @Override  
        protected List<Bitmap> doInBackground(Uri... params) {  
            // TODO Auto-generated method stub  
            List<Bitmap> data = getBitmapFromVideo(params[0]);  
            return data;  
        }  

        @Override  
        protected void onPostExecute(List<Bitmap> result) {  
            listView.setAdapter(new MyThumbnailAdapter(result));  
            super.onPostExecute(result);  
        }  
    }  

    /** 
     * 获取手机上视频的缩略图 
     * @param uri 视频的Uri 
     * @return 
     */  
    private List<Bitmap> getBitmapFromVideo(Uri uri){  

        List<Bitmap> list = new ArrayList<Bitmap>();  
        ContentResolver cr = getContentResolver();  
        Cursor cursor = cr.query(uri, new String[]{Media._ID}, null, null, null);  
        cursor.moveToFirst();  
        do {  
            long id = cursor.getLong(0); // 取得视频的ID,因为我上行只有一个参数所以下标为0  
            BitmapFactory.Options options = new Options();  
            Bitmap bitmap = MediaStore.Video.Thumbnails.getThumbnail(cr, id, MediaStore.Video.Thumbnails.MINI_KIND, options);  
            if (bitmap == null) {  
                Log.e("TAG", "bitmap == null");  
            }  
            list.add(bitmap);  
        } while (cursor.moveToNext());  

        return list;  
    }  

    private class MyThumbnailAdapter extends BaseAdapter{  

        private List<Bitmap> mlist;  


        public MyThumbnailAdapter(List<Bitmap> list) {  
            this.mlist = list;  
        }  

        @Override  
        public int getCount() {  
            // TODO Auto-generated method stub  
            return mlist.size();  
        }  

        @Override  
        public Object getItem(int position) {  
            // TODO Auto-generated method stub  
            return mlist.get(position);  
        }  

        @Override  
        public long getItemId(int position) {  
            // TODO Auto-generated method stub  
            return position;  
        }  

        @Override  
        public View getView(int position, View convertView, ViewGroup parent) {  

            ViewHolder holder  = null;  

            if (convertView == null) {  
                holder = new ViewHolder();  
                convertView = LayoutInflater.from(getApplicationContext()).inflate(R.layout.video_img, null);  
                holder.imageView = (ImageView) convertView.findViewById(R.id.my_img);  
                convertView.setTag(holder);  
            }else{  
                holder = (ViewHolder) convertView.getTag();  
            }  
            holder.imageView.setImageBitmap(mlist.get(position));  
            return convertView;  
        }  

        private class ViewHolder{  
            private ImageView imageView;  
        }  
    }  

}  

很简单XML就不贴了,就一个ListView。通过上面的方法图片缩略图的获取也是一样。

<2> 第二种通过 MediaMetadataRetriever 来获取:
[java] view plain copy

public class MediaMetadataActivity extends Activity{  

    private ProgressDialog dialog = null;  
    private Uri videoUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;  
    private ListView listView;  

    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        // TODO Auto-generated method stub  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.list_view);  

        listView = (ListView) findViewById(R.id.mylistview);  
        dialog = new ProgressDialog(this);  
        dialog.setMessage("加载数据中...");  
        dialog.show();  
        new myAsyncTask().execute(videoUri);  
    }  

    private class myAsyncTask extends AsyncTask<Uri, Void,List<ListItem> >{  

        @Override  
        protected List<ListItem> doInBackground(Uri... params) {  
            // TODO Auto-generated method stub  
            List<VideoItem> videoItems = getMediaPath(params[0]);  
            List<ListItem> items = getListItem(videoItems);  
            return items;  
        }  

        @Override  
        protected void onPostExecute(List<ListItem> result) {  
            // TODO Auto-generated method stub  
            if (dialog!=null) {  
                dialog.dismiss();  
            }  
            listView.setAdapter(new MyAdapter(result));  
            super.onPostExecute(result);  
        }  
    }  

    private List<ListItem> getListItem(List<VideoItem> items){  

        List<ListItem> listItems = new ArrayList<ListItem>();  
        for (int i = 0; i < items.size(); i++) {  

            ListItem item = new ListItem();  
            item.setBitmap(getThumbnail(items.get(i).getPath()));  
            item.setTitle(items.get(i).getTitle());  
            listItems.add(item);  
        }  

        return listItems;  
    }  

    /** 
     * 主要是这个方法通过为MediaMetadataRetriever 设置视频的路径来取得缩略图 
     * @param path 视频的路径 
     * @return 
     */  
    private Bitmap getThumbnail(String path){  

        MediaMetadataRetriever retriever = new MediaMetadataRetriever();  
        retriever.setDataSource(path);  
        Bitmap bitmap = retriever.getFrameAtTime();  
        retriever.release();  
        return bitmap;  
    }  

    private List<VideoItem> getMediaPath(Uri uri){  

        List<VideoItem> mylist = new ArrayList<VideoItem>();  
        String projection[] = {Media.DATA,Media.TITLE,Media.DURATION};  
        Cursor cursor  = getContentResolver().query(uri, projection, null, null, null);  
        cursor.moveToFirst();  
        int count = cursor.getCount();  
        for (int i = 0; i < count; i++) {  

            VideoItem item = new VideoItem();  
            item.setPath(cursor.getString(0));  
            item.setTitle(cursor.getString(1));  
            mylist.add(item);  
            cursor.moveToNext();  
        }  
        return mylist;  
    }  

    private class MyAdapter extends BaseAdapter{  

        List<ListItem> mlist;  

        public MyAdapter(List<ListItem> list) {  
            super();  
            this.mlist = list;  
        }  

        @Override  
        public int getCount() {  
            // TODO Auto-generated method stub  
            return mlist.size();  
        }  

        @Override  
        public Object getItem(int position) {  
            // TODO Auto-generated method stub  
            return mlist.get(position);  
        }  

        @Override  
        public long getItemId(int position) {  
            // TODO Auto-generated method stub  
            return position;  
        }  

        @Override  
        public View getView(int position, View convertView, ViewGroup parent) {  
            ViewHolder holder  = null;  

            if (convertView == null) {  
                holder = new ViewHolder();  
                convertView = LayoutInflater.from(getApplicationContext()).inflate(R.layout.item, null);  
                holder.imageView = (ImageView) convertView.findViewById(R.id.img);  
                holder.textView = (TextView) convertView.findViewById(R.id.tv);  
                convertView.setTag(holder);  
            }else{  
                holder = (ViewHolder) convertView.getTag();  
            }  
            holder.imageView.setImageBitmap(mlist.get(position).getBitmap());  
            holder.textView.setText(mlist.get(position).getTitle());  
            return convertView;  
        }  

        private class ViewHolder{  
            private ImageView imageView;  
            private TextView textView;  
        }  
    }  
}  

MediaMetadataRetriever 除了通过 getFrameAtTime() 方法获取外,还可以用getFrameAtTime(long timeUs)和getFrameAtTime(long timeUs, int option)方法通过时长来获取,这就是获取视频缩略图的两种方式。

  • 6
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值