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

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

// 配置<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

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

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

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

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

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等字段

可以通过常用的字段来查询手机下相应的音频文件:

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

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 查询手机上的图片。

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

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

    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 主要用到这个两个方法:

static Bitmap  getThumbnail(ContentResolver cr, long origId, long groupId, int kind, BitmapFactory.Options options)  
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> 第一种是使用上面介绍的方法:

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 来获取:
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)方法通过时长来获取,这就是获取视频缩略图的两种方式。

以上如果有错的地方,欢迎指出!!O(∩_∩)O~


发布了7 篇原创文章 · 获赞 1 · 访问量 1万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览