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

来源:互联网 发布:收发存excel怎么编程 编辑:程序博客网 时间:2024/05/21 09:55

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

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

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


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


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

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


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

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



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

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

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

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. package com.example.nature;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5.   
  6. import android.content.ContentResolver;  
  7. import android.content.ContentUris;  
  8. import android.database.Cursor;  
  9. import android.net.Uri;  
  10. import android.os.Parcel;  
  11. import android.os.Parcelable;  
  12. import android.provider.MediaStore.Audio.Media;  
  13. import android.util.Log;  
  14.   
  15. public class MusicLoader {  
  16.       
  17.     private static final String TAG = "com.example.nature.MusicLoader";  
  18.       
  19.     private static List<MusicInfo> musicList = new ArrayList<MusicInfo>();  
  20.       
  21.     private static MusicLoader musicLoader;  
  22.       
  23.     private static ContentResolver contentResolver;  
  24.     //Uri,指向external的database   
  25.     private Uri contentUri = Media.EXTERNAL_CONTENT_URI;      
  26.     //projection:选择的列; where:过滤条件; sortOrder:排序。  
  27.     private String[] projection = {  
  28.             Media._ID,  
  29.             Media.DISPLAY_NAME,  
  30.             Media.DATA,  
  31.             Media.ALBUM,  
  32.             Media.ARTIST,  
  33.             Media.DURATION,           
  34.             Media.SIZE  
  35.     };  
  36.     private String where =  "mime_type in ('audio/mpeg','audio/x-ms-wma') and bucket_display_name <> 'audio' and is_music > 0 " ;  
  37.     private String sortOrder = Media.DATA;  
  38.       
  39.     public static MusicLoader instance(ContentResolver pContentResolver){  
  40.         if(musicLoader == null){  
  41.             contentResolver = pContentResolver;  
  42.             musicLoader = new MusicLoader();              
  43.         }  
  44.         return musicLoader;  
  45.     }  
  46.       
  47.     private MusicLoader(){                                                                                                             //利用ContentResolver的query函数来查询数据,然后将得到的结果放到MusicInfo对象中,最后放到数组中  
  48.         Cursor cursor = contentResolver.query(contentUri, projection, where, null, sortOrder);  
  49.         if(cursor == null){  
  50.             Log.v(TAG,"Line(37  )   Music Loader cursor == null.");  
  51.         }else if(!cursor.moveToFirst()){  
  52.             Log.v(TAG,"Line(39  )   Music Loader cursor.moveToFirst() returns false.");  
  53.         }else{            
  54.             int displayNameCol = cursor.getColumnIndex(Media.DISPLAY_NAME);  
  55.             int albumCol = cursor.getColumnIndex(Media.ALBUM);  
  56.             int idCol = cursor.getColumnIndex(Media._ID);  
  57.             int durationCol = cursor.getColumnIndex(Media.DURATION);  
  58.             int sizeCol = cursor.getColumnIndex(Media.SIZE);  
  59.             int artistCol = cursor.getColumnIndex(Media.ARTIST);  
  60.             int urlCol = cursor.getColumnIndex(Media.DATA);           
  61.             do{  
  62.                 String title = cursor.getString(displayNameCol);  
  63.                 String album = cursor.getString(albumCol);  
  64.                 long id = cursor.getLong(idCol);                  
  65.                 int duration = cursor.getInt(durationCol);  
  66.                 long size = cursor.getLong(sizeCol);  
  67.                 String artist = cursor.getString(artistCol);  
  68.                 String url = cursor.getString(urlCol);  
  69.                   
  70.                 MusicInfo musicInfo = new MusicInfo(id, title);  
  71.                 musicInfo.setAlbum(album);  
  72.                 musicInfo.setDuration(duration);  
  73.                 musicInfo.setSize(size);  
  74.                 musicInfo.setArtist(artist);  
  75.                 musicInfo.setUrl(url);  
  76.                 musicList.add(musicInfo);  
  77.                   
  78.             }while(cursor.moveToNext());  
  79.         }  
  80.     }  
  81.       
  82.     public List<MusicInfo> getMusicList(){  
  83.         return musicList;  
  84.     }  
  85.       
  86.     public Uri getMusicUriById(long id){  
  87.         Uri uri = ContentUris.withAppendedId(contentUri, id);  
  88.         return uri;  
  89.     }     
  90.         //下面是自定义的一个MusicInfo子类,实现了Parcelable,为的是可以将整个MusicInfo的ArrayList在Activity和Service中传送,=_=!!,但其实不用  
  91.     static class MusicInfo implements Parcelable{                                         
  92.         private long id;  
  93.         private String title;  
  94.         private String album;  
  95.         private int duration;  
  96.         private long size;  
  97.         private String artist;        
  98.         private String url;       
  99.           
  100.         public MusicInfo(){  
  101.               
  102.         }  
  103.           
  104.         public MusicInfo(long pId, String pTitle){  
  105.             id = pId;  
  106.             title = pTitle;  
  107.         }  
  108.           
  109.         public String getArtist() {  
  110.             return artist;  
  111.         }  
  112.   
  113.         public void setArtist(String artist) {  
  114.             this.artist = artist;  
  115.         }  
  116.   
  117.         public long getSize() {  
  118.             return size;  
  119.         }  
  120.   
  121.         public void setSize(long size) {  
  122.             this.size = size;  
  123.         }         
  124.   
  125.         public long getId() {  
  126.             return id;  
  127.         }  
  128.   
  129.         public void setId(long id) {  
  130.             this.id = id;  
  131.         }  
  132.   
  133.         public String getTitle() {  
  134.             return title;  
  135.         }  
  136.   
  137.         public void setTitle(String title) {  
  138.             this.title = title;  
  139.         }  
  140.   
  141.         public String getAlbum() {  
  142.             return album;  
  143.         }  
  144.   
  145.         public void setAlbum(String album) {  
  146.             this.album = album;  
  147.         }  
  148.   
  149.         public int getDuration() {  
  150.             return duration;  
  151.         }  
  152.   
  153.         public void setDuration(int duration) {  
  154.             this.duration = duration;  
  155.         }     
  156.   
  157.         public String getUrl() {  
  158.             return url;  
  159.         }  
  160.   
  161.         public void setUrl(String url) {  
  162.             this.url = url;  
  163.         }  
  164.   
  165.         @Override  
  166.         public int describeContents() {  
  167.             return 0;  
  168.         }  
  169.   
  170.         @Override  
  171.         public void writeToParcel(Parcel dest, int flags) {  
  172.             dest.writeLong(id);  
  173.             dest.writeString(title);  
  174.             dest.writeString(album);  
  175.             dest.writeString(artist);  
  176.             dest.writeString(url);  
  177.             dest.writeInt(duration);  
  178.             dest.writeLong(size);  
  179.         }  
  180.           
  181.         public static final Parcelable.Creator<MusicInfo>   
  182.             CREATOR = new Creator<MusicLoader.MusicInfo>() {  
  183.               
  184.             @Override  
  185.             public MusicInfo[] newArray(int size) {  
  186.                 return new MusicInfo[size];  
  187.             }  
  188.               
  189.             @Override  
  190.             public MusicInfo createFromParcel(Parcel source) {  
  191.                 MusicInfo musicInfo = new MusicInfo();  
  192.                 musicInfo.setId(source.readLong());  
  193.                 musicInfo.setTitle(source.readString());  
  194.                 musicInfo.setAlbum(source.readString());  
  195.                 musicInfo.setArtist(source.readString());  
  196.                 musicInfo.setUrl(source.readString());  
  197.                 musicInfo.setDuration(source.readInt());  
  198.                 musicInfo.setSize(source.readLong());  
  199.                 return musicInfo;  
  200.             }  
  201.         };  
  202.     }  
  203. }  
[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. package com.example.nature;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5.   
  6. import android.content.ContentResolver;  
  7. import android.content.ContentUris;  
  8. import android.database.Cursor;  
  9. import android.net.Uri;  
  10. import android.os.Parcel;  
  11. import android.os.Parcelable;  
  12. import android.provider.MediaStore.Audio.Media;  
  13. import android.util.Log;  
  14.   
  15. public class MusicLoader {  
  16.       
  17.     private static final String TAG = "com.example.nature.MusicLoader";  
  18.       
  19.     private static List<MusicInfo> musicList = new ArrayList<MusicInfo>();  
  20.       
  21.     private static MusicLoader musicLoader;  
  22.       
  23.     private static ContentResolver contentResolver;  
  24.     //Uri,指向external的database  
  25.     private Uri contentUri = Media.EXTERNAL_CONTENT_URI;      
  26.     //projection:选择的列; where:过滤条件; sortOrder:排序。  
  27.     private String[] projection = {  
  28.             Media._ID,  
  29.             Media.DISPLAY_NAME,  
  30.             Media.DATA,  
  31.             Media.ALBUM,  
  32.             Media.ARTIST,  
  33.             Media.DURATION,           
  34.             Media.SIZE  
  35.     };  
  36.     private String where =  "mime_type in ('audio/mpeg','audio/x-ms-wma') and bucket_display_name <> 'audio' and is_music > 0 " ;  
  37.     private String sortOrder = Media.DATA;  
  38.       
  39.     public static MusicLoader instance(ContentResolver pContentResolver){  
  40.         if(musicLoader == null){  
  41.             contentResolver = pContentResolver;  
  42.             musicLoader = new MusicLoader();              
  43.         }  
  44.         return musicLoader;  
  45.     }  
  46.       
  47.     private MusicLoader(){                                                                                                             //利用ContentResolver的query函数来查询数据,然后将得到的结果放到MusicInfo对象中,最后放到数组中  
  48.         Cursor cursor = contentResolver.query(contentUri, projection, where, null, sortOrder);  
  49.         if(cursor == null){  
  50.             Log.v(TAG,"Line(37  )   Music Loader cursor == null.");  
  51.         }else if(!cursor.moveToFirst()){  
  52.             Log.v(TAG,"Line(39  )   Music Loader cursor.moveToFirst() returns false.");  
  53.         }else{            
  54.             int displayNameCol = cursor.getColumnIndex(Media.DISPLAY_NAME);  
  55.             int albumCol = cursor.getColumnIndex(Media.ALBUM);  
  56.             int idCol = cursor.getColumnIndex(Media._ID);  
  57.             int durationCol = cursor.getColumnIndex(Media.DURATION);  
  58.             int sizeCol = cursor.getColumnIndex(Media.SIZE);  
  59.             int artistCol = cursor.getColumnIndex(Media.ARTIST);  
  60.             int urlCol = cursor.getColumnIndex(Media.DATA);           
  61.             do{  
  62.                 String title = cursor.getString(displayNameCol);  
  63.                 String album = cursor.getString(albumCol);  
  64.                 long id = cursor.getLong(idCol);                  
  65.                 int duration = cursor.getInt(durationCol);  
  66.                 long size = cursor.getLong(sizeCol);  
  67.                 String artist = cursor.getString(artistCol);  
  68.                 String url = cursor.getString(urlCol);  
  69.                   
  70.                 MusicInfo musicInfo = new MusicInfo(id, title);  
  71.                 musicInfo.setAlbum(album);  
  72.                 musicInfo.setDuration(duration);  
  73.                 musicInfo.setSize(size);  
  74.                 musicInfo.setArtist(artist);  
  75.                 musicInfo.setUrl(url);  
  76.                 musicList.add(musicInfo);  
  77.                   
  78.             }while(cursor.moveToNext());  
  79.         }  
  80.     }  
  81.       
  82.     public List<MusicInfo> getMusicList(){  
  83.         return musicList;  
  84.     }  
  85.       
  86.     public Uri getMusicUriById(long id){  
  87.         Uri uri = ContentUris.withAppendedId(contentUri, id);  
  88.         return uri;  
  89.     }     
  90.         //下面是自定义的一个MusicInfo子类,实现了Parcelable,为的是可以将整个MusicInfo的ArrayList在Activity和Service中传送,=_=!!,但其实不用  
  91.     static class MusicInfo implements Parcelable{                                         
  92.         private long id;  
  93.         private String title;  
  94.         private String album;  
  95.         private int duration;  
  96.         private long size;  
  97.         private String artist;        
  98.         private String url;       
  99.           
  100.         public MusicInfo(){  
  101.               
  102.         }  
  103.           
  104.         public MusicInfo(long pId, String pTitle){  
  105.             id = pId;  
  106.             title = pTitle;  
  107.         }  
  108.           
  109.         public String getArtist() {  
  110.             return artist;  
  111.         }  
  112.   
  113.         public void setArtist(String artist) {  
  114.             this.artist = artist;  
  115.         }  
  116.   
  117.         public long getSize() {  
  118.             return size;  
  119.         }  
  120.   
  121.         public void setSize(long size) {  
  122.             this.size = size;  
  123.         }         
  124.   
  125.         public long getId() {  
  126.             return id;  
  127.         }  
  128.   
  129.         public void setId(long id) {  
  130.             this.id = id;  
  131.         }  
  132.   
  133.         public String getTitle() {  
  134.             return title;  
  135.         }  
  136.   
  137.         public void setTitle(String title) {  
  138.             this.title = title;  
  139.         }  
  140.   
  141.         public String getAlbum() {  
  142.             return album;  
  143.         }  
  144.   
  145.         public void setAlbum(String album) {  
  146.             this.album = album;  
  147.         }  
  148.   
  149.         public int getDuration() {  
  150.             return duration;  
  151.         }  
  152.   
  153.         public void setDuration(int duration) {  
  154.             this.duration = duration;  
  155.         }     
  156.   
  157.         public String getUrl() {  
  158.             return url;  
  159.         }  
  160.   
  161.         public void setUrl(String url) {  
  162.             this.url = url;  
  163.         }  
  164.   
  165.         @Override  
  166.         public int describeContents() {  
  167.             return 0;  
  168.         }  
  169.   
  170.         @Override  
  171.         public void writeToParcel(Parcel dest, int flags) {  
  172.             dest.writeLong(id);  
  173.             dest.writeString(title);  
  174.             dest.writeString(album);  
  175.             dest.writeString(artist);  
  176.             dest.writeString(url);  
  177.             dest.writeInt(duration);  
  178.             dest.writeLong(size);  
  179.         }  
  180.           
  181.         public static final Parcelable.Creator<MusicInfo>   
  182.             CREATOR = new Creator<MusicLoader.MusicInfo>() {  
  183.               
  184.             @Override  
  185.             public MusicInfo[] newArray(int size) {  
  186.                 return new MusicInfo[size];  
  187.             }  
  188.               
  189.             @Override  
  190.             public MusicInfo createFromParcel(Parcel source) {  
  191.                 MusicInfo musicInfo = new MusicInfo();  
  192.                 musicInfo.setId(source.readLong());  
  193.                 musicInfo.setTitle(source.readString());  
  194.                 musicInfo.setAlbum(source.readString());  
  195.                 musicInfo.setArtist(source.readString());  
  196.                 musicInfo.setUrl(source.readString());  
  197.                 musicInfo.setDuration(source.readInt());  
  198.                 musicInfo.setSize(source.readLong());  
  199.                 return musicInfo;  
  200.             }  
  201.         };  
  202.     }  
  203. }  
最后,我们就可以在我们的手机上看到我们音乐了,不过数据库中有些是乱码的,我还不知道怎么解决。。。

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

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. package com.example.hmgallery;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5.   
  6. import android.content.ContentResolver;  
  7. import android.database.Cursor;  
  8. import android.provider.MediaStore.Images.Media;  
  9. import android.provider.MediaStore.Images.Thumbnails;  
  10. import android.util.SparseArray;  
  11.   
  12. public class Images{  
  13.   
  14.     public static final String IMAGE_PATH = "IMAGE_PATH";  
  15.     public static final String IMAGE_ID = "IMAGE_ID";  
  16.     public static final String IMAGE_POSITION = "IMAGE_POSITION";  
  17.     public static final String IMAGE_COUNTS = "IMAGE_COUNTS";     
  18.       
  19.     private static List<ImageItem> imageItems = new ArrayList<ImageItem>();  
  20.       
  21.     private static SparseArray<ImageItem> tempArray;  
  22.       
  23.     public static void loadImages(ContentResolver contentResolver){  
  24.         tempArray = new SparseArray<ImageItem>();  
  25.         String[] projection = {Media._ID,Media.DATA,Media.ORIENTATION};  
  26.         String where =  Media.BUCKET_DISPLAY_NAME + " = 'Camera'";  
  27.         String sortOrder = Media._ID + " desc";  
  28.         StringBuilder inImageIds = new StringBuilder(Thumbnails.IMAGE_ID);  
  29.         inImageIds.append(" in ( ");  
  30.         Cursor cursor = contentResolver.query(Media.EXTERNAL_CONTENT_URI, projection, where, null, sortOrder);        
  31.         if(cursor.moveToFirst()){  
  32.             do {  
  33.                 int imageId = cursor.getInt(cursor.getColumnIndex(Media._ID));  
  34.                 String imagePath = cursor.getString(cursor.getColumnIndex(Media.DATA));  
  35.                 int orientation = cursor.getInt(cursor.getColumnIndex(Media.ORIENTATION));  
  36.                 ImageItem imageItem = new ImageItem(imageId,imagePath,orientation);               
  37.                 imageItems.add(imageItem);  
  38.                 tempArray.put(imageId, imageItem);  
  39.                 inImageIds.append(imageId).append(",");  
  40.             }while(cursor.moveToNext());  
  41.         }         
  42.           
  43.         inImageIds.deleteCharAt(inImageIds.length() - 1);  
  44.         inImageIds.append(" ) ");   
  45.           
  46.         String[] thumbnailProjection = {Thumbnails.DATA,Thumbnails.IMAGE_ID};  
  47.         cursor = contentResolver.query(Thumbnails.EXTERNAL_CONTENT_URI, thumbnailProjection, inImageIds.toString(), nullnull);  
  48.         if(cursor.moveToFirst()){  
  49.             do {                  
  50.                 int imageId = cursor.getInt(cursor.getColumnIndex(Thumbnails.IMAGE_ID));  
  51.                 String thumnbailPath = cursor.getString(cursor.getColumnIndex(Media.DATA));               
  52.                 ImageItem imageItem = tempArray.get(imageId);  
  53.                 if(imageItem != null){  
  54.                     imageItem.setThumbnailPath(thumnbailPath);  
  55.                 }  
  56.             }while(cursor.moveToNext());  
  57.         }         
  58.         tempArray = null;  
  59.     }  
  60.       
  61.     public static ImageItem[] getImageItems(){  
  62.         return imageItems.toArray(new ImageItem[]{});  
  63.     }     
  64. }  
[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. package com.example.hmgallery;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5.   
  6. import android.content.ContentResolver;  
  7. import android.database.Cursor;  
  8. import android.provider.MediaStore.Images.Media;  
  9. import android.provider.MediaStore.Images.Thumbnails;  
  10. import android.util.SparseArray;  
  11.   
  12. public class Images{  
  13.   
  14.     public static final String IMAGE_PATH = "IMAGE_PATH";  
  15.     public static final String IMAGE_ID = "IMAGE_ID";  
  16.     public static final String IMAGE_POSITION = "IMAGE_POSITION";  
  17.     public static final String IMAGE_COUNTS = "IMAGE_COUNTS";     
  18.       
  19.     private static List<ImageItem> imageItems = new ArrayList<ImageItem>();  
  20.       
  21.     private static SparseArray<ImageItem> tempArray;  
  22.       
  23.     public static void loadImages(ContentResolver contentResolver){  
  24.         tempArray = new SparseArray<ImageItem>();  
  25.         String[] projection = {Media._ID,Media.DATA,Media.ORIENTATION};  
  26.         String where =  Media.BUCKET_DISPLAY_NAME + " = 'Camera'";  
  27.         String sortOrder = Media._ID + " desc";  
  28.         StringBuilder inImageIds = new StringBuilder(Thumbnails.IMAGE_ID);  
  29.         inImageIds.append(" in ( ");  
  30.         Cursor cursor = contentResolver.query(Media.EXTERNAL_CONTENT_URI, projection, where, null, sortOrder);        
  31.         if(cursor.moveToFirst()){  
  32.             do {  
  33.                 int imageId = cursor.getInt(cursor.getColumnIndex(Media._ID));  
  34.                 String imagePath = cursor.getString(cursor.getColumnIndex(Media.DATA));  
  35.                 int orientation = cursor.getInt(cursor.getColumnIndex(Media.ORIENTATION));  
  36.                 ImageItem imageItem = new ImageItem(imageId,imagePath,orientation);               
  37.                 imageItems.add(imageItem);  
  38.                 tempArray.put(imageId, imageItem);  
  39.                 inImageIds.append(imageId).append(",");  
  40.             }while(cursor.moveToNext());  
  41.         }         
  42.           
  43.         inImageIds.deleteCharAt(inImageIds.length() - 1);  
  44.         inImageIds.append(" ) ");   
  45.           
  46.         String[] thumbnailProjection = {Thumbnails.DATA,Thumbnails.IMAGE_ID};  
  47.         cursor = contentResolver.query(Thumbnails.EXTERNAL_CONTENT_URI, thumbnailProjection, inImageIds.toString(), nullnull);  
  48.         if(cursor.moveToFirst()){  
  49.             do {                  
  50.                 int imageId = cursor.getInt(cursor.getColumnIndex(Thumbnails.IMAGE_ID));  
  51.                 String thumnbailPath = cursor.getString(cursor.getColumnIndex(Media.DATA));               
  52.                 ImageItem imageItem = tempArray.get(imageId);  
  53.                 if(imageItem != null){  
  54.                     imageItem.setThumbnailPath(thumnbailPath);  
  55.                 }  
  56.             }while(cursor.moveToNext());  
  57.         }         
  58.         tempArray = null;  
  59.     }  
  60.       
  61.     public static ImageItem[] getImageItems(){  
  62.         return imageItems.toArray(new ImageItem[]{});  
  63.     }     
  64. }  
0 0