相冊的列表頁面是GalleryPicker,當加載列表數據的時候會執行下面這個方法: java
private void workerRun() { ArrayList<Item> allItems = new ArrayList<Item>(); checkScanning();//檢查系統Media庫掃描後臺是否還在執行 ..... checkImageList(allItems);//獲取系統媒體數據列表,這裏就包括全部的圖片文件夾列表、相機圖片、相機視頻、全部圖片、全部視頻 ..... checkBucketIds(allItems);//下面是獲取sdcard文件夾列表數據 ps:我的以爲這個方法和上面的checkImageList方法的名字頗有歧義啊。根據方法名很容易理解爲checkImageList是先獲取整個列表,checkBucketIds方法是獲取列表須要的數據。被名字忽悠了。應該叫作checkInternalList 和 checkExternalList嘛。 checkThumbBitmap(allItems); checkLowStorage(); }下面是獲取系統媒體列表數據,列表有5類,包括相機圖片、相機視頻、相機媒體(相機圖片+相機視頻)、全部圖片、全部視頻
private void checkImageList(ArrayList<Item> allItems) { int length = IMAGE_LIST_DATA.length;//5類列表的數據所有定義在IMAGE_LIST_DATA裏面 IImageList[] lists = new IImageList[length]; for (int i = 0; i < length; i++) { ImageListData data = IMAGE_LIST_DATA[i]; lists[i] = createImageList(data.mInclude, data.mBucketId, getContentResolver()); ..... Item item = new Item(data.mType, data.mBucketId, getResources() .getString(data.mStringId), lists[i]); allItems.add(item); final Item finalItem = item; mHandler.post(new Runnable() { public void run() { updateItem(finalItem); } }); } }裏面抽象定義的數據比較多,這裏介紹不可能太清楚。能夠取看看代碼,仔細研究一下。整體說來,這裏獲得相機圖片、相機視頻、相機媒體(相機圖片+相機視頻)、全部圖片、全部視頻這幾種數據的列表。列表的結構是ImageList、VideoList等,它們都是BaseImageList的子類,代碼在com.android.camera.gallery包下面。
下面是獲取sdcard文件夾列表數據 android
private void checkBucketIds(ArrayList<Item> allItems) { final IImageList allImages; //獲取全部數據列表 if (!mScanning && !mUnmounted) { allImages = ImageManager.makeImageList(getContentResolver(), ImageManager.DataLocation.ALL, ImageManager.INCLUDE_IMAGES | ImageManager.INCLUDE_VIDEOS, ImageManager.SORT_DESCENDING, null); } else { allImages = ImageManager.makeEmptyImageList(); } ..... //這個地方這句話,是比較屌的,直接就查到了sdcard中的文件夾列表。之前,本身寫這一塊。就很2地取Media數據庫,把全部的圖片文件路徑讀出來,在來截取生成列表。相冊是否是這樣寫的,具體,下面會介紹 HashMap<String, String> hashMap = allImages.getBucketIds(); allImages.close(); for (Map.Entry<String, String> entry : hashMap.entrySet()) { String key = entry.getKey(); if (!key.equals(CAMERA_BUCKET)) { IImageList list = createImageList(ImageManager.INCLUDE_IMAGES | ImageManager.INCLUDE_VIDEOS, key, getContentResolver()); ..... Item item = new Item(Item.TYPE_NORMAL_FOLDERS, key, entry.getValue(), list); allItems.add(item); final Item finalItem = item; mHandler.post(new Runnable() { public void run() { updateItem(finalItem); } }); } } mHandler.post(new Runnable() { public void run() { checkBucketIdsFinished(); } }); }
上面的所有都是招式,下面纔是內功,也就是獲取列表的核心部分,因爲相冊把這一塊作了不少抽象,所以,我把核心的代碼整理出來 ios
package com.example.demo; import java.util.HashMap; import android.content.ContentResolver; import android.database.Cursor; import android.net.Uri; import android.os.Environment; import android.provider.MediaStore.Images; import android.provider.MediaStore.Images.Media; /** * 獲取系統Midia數據庫數據,Midia數據庫要這麼用 * * @author johnnyxyz * @mail johnnyxyzw@gmail.com */ public class MediaListGetter { public static final Uri EXTERNAL_STORAGE_URI = Images.Media.EXTERNAL_CONTENT_URI; public static final Uri INTERNAL_STORAGE_URI = Images.Media.INTERNAL_CONTENT_URI; public static final Uri VIDEO_STORAGE_URI = Uri.parse("content://media/external/video/media"); private static final String[] ACCEPTABLE_IMAGE_TYPES = new String[] { "image/jpeg", "image/png", "image/gif" }; private static final String WHERE_CLAUSE = "(" + Media.MIME_TYPE + " in (?, ?, ?))"; private static final String WHERE_CLAUSE_WITH_BUCKET_ID = WHERE_CLAUSE + " AND " + Media.BUCKET_ID + " = ?"; protected String whereClause(String bucketId) { return bucketId == null ? WHERE_CLAUSE : WHERE_CLAUSE_WITH_BUCKET_ID; } private String[] whereClauseArgs(String bucketId) { if (bucketId != null) { int count = ACCEPTABLE_IMAGE_TYPES.length; String[] result = new String[count + 1]; System.arraycopy(ACCEPTABLE_IMAGE_TYPES, 0, result, 0, count); result[count] = bucketId; return result; } return ACCEPTABLE_IMAGE_TYPES; } public static final String CAMERA_IMAGE_BUCKET_NAME = Environment.getExternalStorageDirectory() .toString() + "/DCIM/Camera"; public static final String CAMERA_IMAGE_BUCKET_ID = String.valueOf(CAMERA_IMAGE_BUCKET_NAME .toLowerCase().hashCode()); public MediaListGetter(ContentResolver mContentResolver) { super(); this.mContentResolver = mContentResolver; } private final ContentResolver mContentResolver; /** * 獲取全部Camera圖片文件夾列表 * @return */ public HashMap<String, String> getCameraImages() { // 內置存儲的圖片 Uri baseUri = INTERNAL_STORAGE_URI; Uri uri = baseUri.buildUpon().appendQueryParameter("distinct", "true").build(); Cursor internal = Media.query(mContentResolver, uri, new String[] { Media.BUCKET_DISPLAY_NAME, Media.BUCKET_ID }, whereClause(CAMERA_IMAGE_BUCKET_ID), whereClauseArgs(CAMERA_IMAGE_BUCKET_ID), null); // 外置存儲的圖片 baseUri = EXTERNAL_STORAGE_URI; uri = baseUri.buildUpon().appendQueryParameter("distinct", "true").build(); Cursor external = Media.query(mContentResolver, uri, new String[] { Media.BUCKET_DISPLAY_NAME, Media.BUCKET_ID }, whereClause(CAMERA_IMAGE_BUCKET_ID), whereClauseArgs(CAMERA_IMAGE_BUCKET_ID), null); try { HashMap<String, String> hash = new HashMap<String, String>(); while (internal.moveToNext()) { hash.put(internal.getString(1), internal.getString(0)); } while (external.moveToNext()) { hash.put(external.getString(1), external.getString(0)); } return hash; } finally { internal.close(); external.close(); } } /** * 獲取全部Camera視頻文件夾列表 * @return */ public HashMap<String, String> getCameraVidios() { Uri baseUri = VIDEO_STORAGE_URI; Uri uri = baseUri.buildUpon().appendQueryParameter("distinct", "true").build(); Cursor cursor = Media.query(mContentResolver, uri, new String[] { Media.BUCKET_DISPLAY_NAME, Media.BUCKET_ID }, (CAMERA_IMAGE_BUCKET_ID != null ? Images.Media.BUCKET_ID + " = '" + CAMERA_IMAGE_BUCKET_ID + "'" : null), null, null); try { HashMap<String, String> hash = new HashMap<String, String>(); while (cursor.moveToNext()) { hash.put(cursor.getString(1), cursor.getString(0)); } return hash; } finally { cursor.close(); } }; /** * 獲取全部Camera媒體文件夾列表 * @return */ public void getCameraMedias() { // getCameraVidios + getCameraImages }; /** * 獲取全部圖片的文件夾列表 * @return */ public HashMap<String, String> getAllImages() { Uri baseUri = EXTERNAL_STORAGE_URI; Uri uri = baseUri.buildUpon().appendQueryParameter("distinct", "true").build(); // 外置存儲camera圖片 Cursor camera = Media.query(mContentResolver, uri, new String[] { Media.BUCKET_DISPLAY_NAME, Media.BUCKET_ID }, whereClause(CAMERA_IMAGE_BUCKET_ID), whereClauseArgs(CAMERA_IMAGE_BUCKET_ID), null); // 外置存儲非camera圖片 Cursor external = Media.query(mContentResolver, uri, new String[] { Media.BUCKET_DISPLAY_NAME, Media.BUCKET_ID }, whereClause(null), whereClauseArgs(null), null); // 內置圖片 baseUri = INTERNAL_STORAGE_URI; uri = baseUri.buildUpon().appendQueryParameter("distinct", "true").build(); Cursor internal = Media.query(mContentResolver, uri, new String[] { Media.BUCKET_DISPLAY_NAME, Media.BUCKET_ID }, whereClause(null), whereClauseArgs(null), null); try { HashMap<String, String> hash = new HashMap<String, String>(); while (camera.moveToNext()) { hash.put(camera.getString(1), camera.getString(0)); } while (external.moveToNext()) { hash.put(external.getString(1), external.getString(0)); } while (internal.moveToNext()) { hash.put(internal.getString(1), internal.getString(0)); } return hash; } finally { camera.close(); external.close(); internal.close(); } }; /** * 獲取全部視頻的文件夾列表 * @return */ public HashMap<String, String> getAllVidios() { Uri baseUri = VIDEO_STORAGE_URI; Uri uri = baseUri.buildUpon().appendQueryParameter("distinct", "true").build(); Cursor cursor = Media.query(mContentResolver, uri, new String[] { Media.BUCKET_DISPLAY_NAME, Media.BUCKET_ID }, null, null, null); try { HashMap<String, String> hash = new HashMap<String, String>(); while (cursor.moveToNext()) { hash.put(cursor.getString(1), cursor.getString(0)); } return hash; } finally { cursor.close(); } }; /** * 獲取外置存儲的全部文件夾 * @return */ public HashMap<String, String> getExternalFolders() { Uri baseUri = EXTERNAL_STORAGE_URI; Uri uri = baseUri.buildUpon().appendQueryParameter("distinct", "true").build(); Cursor cursor = Media.query(mContentResolver, uri, new String[] { Media.BUCKET_DISPLAY_NAME, Media.BUCKET_ID }, null, null, null); try { HashMap<String, String> hash = new HashMap<String, String>(); while (cursor.moveToNext()) { if (CAMERA_IMAGE_BUCKET_ID.equals(cursor.getString(1))) continue; hash.put(cursor.getString(1), cursor.getString(0)); } return hash; } finally { cursor.close(); } } }
若是想要下載完整示例代碼,可戳這裏 https://github.com/sevenler/Android_Demos.git 。這個Demos裏面有其餘示例代碼。跑起來仍是很容易找到本示例的代碼的。 git
....未完待續.... github