相册的列表页面是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