`
yanfaguanli
  • 浏览: 662153 次
文章分类
社区版块
存档分类
最新评论

Android中利用ContentResolver获取本地音乐和相片

 
阅读更多

在Android中,例如图库和音乐播放器,它们能够扫描我们的系统,获取到本地的相片跟音乐,这一点是如何做到的呢?

当我们往手机上放图片或者音乐的时候,会在手机内存中某个位置上的某个database中存放图片或者音乐的信息,而我们的应用程序是能够通过ContentResolver去读取到这些数据的。

下面可以先看一下database在哪,如下:


然后在data/data/下面呢,有很多provider提供的数据库,而我们的音乐或者图片就是在一个叫做Media的库下:


external是智能手机中内置的SD卡,而internal则是机身的内存。

这两个database里面的结构是一样的,我们把external给拉到本地电脑上,如下红色框框显示的,左边就是从手机SD卡拉到电脑,右边是从电脑推到手机SD卡上。


接下来可以利用SQLiteSpy之类的工具打开我们的数据库,可以看到Images 和 Audio 相关的表和视图:

比如图片,我们可以查看images这张表,其结构如下:



音乐,可以查看audio的视图,如下:

既然知道了这些表的数据结构,那么如何在我们的应用程序中去获取到这些数据呢?答案,当然就是利用ContentResolver了。

具体看代码,下面我写的一个MusicLoader,是为了获取本地音乐,其中利用了一些过滤条件,只拿出我想要的音乐。

package com.example.nature;

import java.util.ArrayList;
import java.util.List;

import android.content.ContentResolver;
import android.content.ContentUris;
import android.database.Cursor;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
import android.provider.MediaStore.Audio.Media;
import android.util.Log;

public class MusicLoader {
	
	private static final String TAG = "com.example.nature.MusicLoader";
	
	private static List<MusicInfo> musicList = new ArrayList<MusicInfo>();
	
	private static MusicLoader musicLoader;
	
	private static ContentResolver contentResolver;
	//Uri,指向external的database
	private Uri contentUri = Media.EXTERNAL_CONTENT_URI;	
	//projection:选择的列; where:过滤条件; sortOrder:排序。
	private String[] projection = {
			Media._ID,
			Media.DISPLAY_NAME,
			Media.DATA,
			Media.ALBUM,
			Media.ARTIST,
			Media.DURATION,			
			Media.SIZE
	};
	private String where =  "mime_type in ('audio/mpeg','audio/x-ms-wma') and bucket_display_name <> 'audio' and is_music > 0 " ;
	private String sortOrder = Media.DATA;
	
	public static MusicLoader instance(ContentResolver pContentResolver){
		if(musicLoader == null){
			contentResolver = pContentResolver;
			musicLoader = new MusicLoader();			
		}
		return musicLoader;
	}
	
	private MusicLoader(){		                                                                                                       //利用ContentResolver的query函数来查询数据,然后将得到的结果放到MusicInfo对象中,最后放到数组中
		Cursor cursor = contentResolver.query(contentUri, projection, where, null, sortOrder);
		if(cursor == null){
			Log.v(TAG,"Line(37	)	Music Loader cursor == null.");
		}else if(!cursor.moveToFirst()){
			Log.v(TAG,"Line(39	)	Music Loader cursor.moveToFirst() returns false.");
		}else{			
			int displayNameCol = cursor.getColumnIndex(Media.DISPLAY_NAME);
			int albumCol = cursor.getColumnIndex(Media.ALBUM);
			int idCol = cursor.getColumnIndex(Media._ID);
			int durationCol = cursor.getColumnIndex(Media.DURATION);
			int sizeCol = cursor.getColumnIndex(Media.SIZE);
			int artistCol = cursor.getColumnIndex(Media.ARTIST);
			int urlCol = cursor.getColumnIndex(Media.DATA);			
			do{
				String title = cursor.getString(displayNameCol);
				String album = cursor.getString(albumCol);
				long id = cursor.getLong(idCol);				
				int duration = cursor.getInt(durationCol);
				long size = cursor.getLong(sizeCol);
				String artist = cursor.getString(artistCol);
				String url = cursor.getString(urlCol);
				
				MusicInfo musicInfo = new MusicInfo(id, title);
				musicInfo.setAlbum(album);
				musicInfo.setDuration(duration);
				musicInfo.setSize(size);
				musicInfo.setArtist(artist);
				musicInfo.setUrl(url);
				musicList.add(musicInfo);
				
			}while(cursor.moveToNext());
		}
	}
	
	public List<MusicInfo> getMusicList(){
		return musicList;
	}
	
	public Uri getMusicUriById(long id){
		Uri uri = ContentUris.withAppendedId(contentUri, id);
		return uri;
	}	
        //下面是自定义的一个MusicInfo子类,实现了Parcelable,为的是可以将整个MusicInfo的ArrayList在Activity和Service中传送,=_=!!,但其实不用
	static class MusicInfo implements Parcelable{										
		private long id;
		private String title;
		private String album;
		private int duration;
		private long size;
		private String artist;		
		private String url;		
		
		public MusicInfo(){
			
		}
		
		public MusicInfo(long pId, String pTitle){
			id = pId;
			title = pTitle;
		}
		
		public String getArtist() {
			return artist;
		}

		public void setArtist(String artist) {
			this.artist = artist;
		}

		public long getSize() {
			return size;
		}

		public void setSize(long size) {
			this.size = size;
		}		

		public long getId() {
			return id;
		}

		public void setId(long id) {
			this.id = id;
		}

		public String getTitle() {
			return title;
		}

		public void setTitle(String title) {
			this.title = title;
		}

		public String getAlbum() {
			return album;
		}

		public void setAlbum(String album) {
			this.album = album;
		}

		public int getDuration() {
			return duration;
		}

		public void setDuration(int duration) {
			this.duration = duration;
		}	

		public String getUrl() {
			return url;
		}

		public void setUrl(String url) {
			this.url = url;
		}

		@Override
		public int describeContents() {
			return 0;
		}

		@Override
		public void writeToParcel(Parcel dest, int flags) {
			dest.writeLong(id);
			dest.writeString(title);
			dest.writeString(album);
			dest.writeString(artist);
			dest.writeString(url);
			dest.writeInt(duration);
			dest.writeLong(size);
		}
		
		public static final Parcelable.Creator<MusicInfo> 
			CREATOR = new Creator<MusicLoader.MusicInfo>() {
			
			@Override
			public MusicInfo[] newArray(int size) {
				return new MusicInfo[size];
			}
			
			@Override
			public MusicInfo createFromParcel(Parcel source) {
				MusicInfo musicInfo = new MusicInfo();
				musicInfo.setId(source.readLong());
				musicInfo.setTitle(source.readString());
				musicInfo.setAlbum(source.readString());
				musicInfo.setArtist(source.readString());
				musicInfo.setUrl(source.readString());
				musicInfo.setDuration(source.readInt());
				musicInfo.setSize(source.readLong());
				return musicInfo;
			}
		};
	}
}
最后,我们就可以在我们的手机上看到我们音乐了,不过数据库中有些是乱码的,我还不知道怎么解决。。。

图片的获取也是相类似的,放上代码,具体的自行琢磨:

package com.example.hmgallery;

import java.util.ArrayList;
import java.util.List;

import android.content.ContentResolver;
import android.database.Cursor;
import android.provider.MediaStore.Images.Media;
import android.provider.MediaStore.Images.Thumbnails;
import android.util.SparseArray;

public class Images{

	public static final String IMAGE_PATH = "IMAGE_PATH";
	public static final String IMAGE_ID = "IMAGE_ID";
	public static final String IMAGE_POSITION = "IMAGE_POSITION";
	public static final String IMAGE_COUNTS = "IMAGE_COUNTS";	
	
	private static List<ImageItem> imageItems = new ArrayList<ImageItem>();
	
	private static SparseArray<ImageItem> tempArray;
	
	public static void loadImages(ContentResolver contentResolver){
		tempArray = new SparseArray<ImageItem>();
		String[] projection = {Media._ID,Media.DATA,Media.ORIENTATION};
		String where =  Media.BUCKET_DISPLAY_NAME + " = 'Camera'";
		String sortOrder = Media._ID + " desc";
		StringBuilder inImageIds = new StringBuilder(Thumbnails.IMAGE_ID);
		inImageIds.append(" in ( ");
		Cursor cursor = contentResolver.query(Media.EXTERNAL_CONTENT_URI, projection, where, null, sortOrder);		
		if(cursor.moveToFirst()){
			do {
				int imageId = cursor.getInt(cursor.getColumnIndex(Media._ID));
				String imagePath = cursor.getString(cursor.getColumnIndex(Media.DATA));
				int orientation = cursor.getInt(cursor.getColumnIndex(Media.ORIENTATION));
				ImageItem imageItem = new ImageItem(imageId,imagePath,orientation);				
				imageItems.add(imageItem);
				tempArray.put(imageId, imageItem);
				inImageIds.append(imageId).append(",");
			}while(cursor.moveToNext());
		}		
		
		inImageIds.deleteCharAt(inImageIds.length() - 1);
		inImageIds.append(" ) "); 
		
		String[] thumbnailProjection = {Thumbnails.DATA,Thumbnails.IMAGE_ID};
		cursor = contentResolver.query(Thumbnails.EXTERNAL_CONTENT_URI, thumbnailProjection, inImageIds.toString(), null, null);
		if(cursor.moveToFirst()){
			do {				
				int imageId = cursor.getInt(cursor.getColumnIndex(Thumbnails.IMAGE_ID));
				String thumnbailPath = cursor.getString(cursor.getColumnIndex(Media.DATA));				
				ImageItem imageItem = tempArray.get(imageId);
				if(imageItem != null){
					imageItem.setThumbnailPath(thumnbailPath);
				}
			}while(cursor.moveToNext());
		}		
		tempArray = null;
	}
	
	public static ImageItem[] getImageItems(){
		return imageItems.toArray(new ImageItem[]{});
	}	
}


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics