Android之MediaStore
Posted 胖子luffy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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)方法通过时长来获取,这就是获取视频缩略图的两种方式。
以上是关于Android之MediaStore的主要内容,如果未能解决你的问题,请参考以下文章
MediaStore 与Media.EXTERNAL_CONTENT_URI
ContentProvider之通过ContentResolver获取图像视频音频举例
ContentProvider之通过ContentResolver获取图像视频音频举例