1f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin/* 2f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Copyright (C) 2010 The Android Open Source Project 3f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * 4f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Licensed under the Apache License, Version 2.0 (the "License"); 5f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * you may not use this file except in compliance with the License. 6f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * You may obtain a copy of the License at 7f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * 8f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * http://www.apache.org/licenses/LICENSE-2.0 9f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * 10f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Unless required by applicable law or agreed to in writing, software 11f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * distributed under the License is distributed on an "AS IS" BASIS, 12f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * See the License for the specific language governing permissions and 14f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * limitations under the License. 15f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin */ 16f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 17f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linpackage com.android.gallery3d.data; 18f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 19f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.content.ContentResolver; 206caf221c4888f8632e8eb5b60b145bfca3557b3aChih-Chung Changimport android.content.res.Resources; 21f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.database.Cursor; 22f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.net.Uri; 23fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liuimport android.os.Environment; 2484c220f10a643927c8a2126de8a755d8d7f7ec9eRay Chenimport android.provider.MediaStore; 25f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.provider.MediaStore.Images; 26f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.provider.MediaStore.Images.ImageColumns; 27f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.provider.MediaStore.Video; 28f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.provider.MediaStore.Video.VideoColumns; 29f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 302b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport com.android.gallery3d.R; 312b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport com.android.gallery3d.app.GalleryApp; 322b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport com.android.gallery3d.common.Utils; 33fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liuimport com.android.gallery3d.util.BucketNames; 342b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport com.android.gallery3d.util.GalleryUtils; 352b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport com.android.gallery3d.util.MediaSetUtils; 362b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Lin 37fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liuimport java.io.File; 38f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport java.util.ArrayList; 39f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 40f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// LocalAlbumSet lists all media items in one bucket on local storage. 41f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin// The media items need to be all images or all videos, but not both. 42f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linpublic class LocalAlbum extends MediaSet { 43f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final String TAG = "LocalAlbum"; 44f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final String[] COUNT_PROJECTION = { "count(*)" }; 45f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 46f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final int INVALID_COUNT = -1; 47f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final String mWhereClause; 48f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final String mOrderClause; 49f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final Uri mBaseUri; 50f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final String[] mProjection; 51f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 52f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final GalleryApp mApplication; 53f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final ContentResolver mResolver; 54f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final int mBucketId; 556caf221c4888f8632e8eb5b60b145bfca3557b3aChih-Chung Chang private final String mName; 56f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final boolean mIsImage; 57f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final ChangeNotifier mNotifier; 58f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final Path mItemPath; 59f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private int mCachedCount = INVALID_COUNT; 60f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 61f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public LocalAlbum(Path path, GalleryApp application, int bucketId, 62f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin boolean isImage, String name) { 63f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin super(path, nextVersionNumber()); 64f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mApplication = application; 65f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mResolver = application.getContentResolver(); 66f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mBucketId = bucketId; 67ef1e404cfa1227e309786675a6026dec842b5ab1Bobby Georgescu mName = name; 68f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mIsImage = isImage; 69f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 70f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (isImage) { 71f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mWhereClause = ImageColumns.BUCKET_ID + " = ?"; 72f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mOrderClause = ImageColumns.DATE_TAKEN + " DESC, " 73f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin + ImageColumns._ID + " DESC"; 74f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mBaseUri = Images.Media.EXTERNAL_CONTENT_URI; 75f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mProjection = LocalImage.PROJECTION; 76f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mItemPath = LocalImage.ITEM_PATH; 77f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } else { 78f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mWhereClause = VideoColumns.BUCKET_ID + " = ?"; 79f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mOrderClause = VideoColumns.DATE_TAKEN + " DESC, " 80f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin + VideoColumns._ID + " DESC"; 81f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mBaseUri = Video.Media.EXTERNAL_CONTENT_URI; 82f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mProjection = LocalVideo.PROJECTION; 83f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mItemPath = LocalVideo.ITEM_PATH; 84f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 85f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 86f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mNotifier = new ChangeNotifier(this, mBaseUri, application); 87f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 88f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 89f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public LocalAlbum(Path path, GalleryApp application, int bucketId, 90f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin boolean isImage) { 91f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin this(path, application, bucketId, isImage, 9290df352389eda7c964e6a43a0b752d27f16e02a7Owen Lin BucketHelper.getBucketName( 9390df352389eda7c964e6a43a0b752d27f16e02a7Owen Lin application.getContentResolver(), bucketId)); 94f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 95f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 96f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 977eea4d3ac59aa88d327fc0d58f5e4052f43c54c9Bobby Georgescu public boolean isCameraRoll() { 987eea4d3ac59aa88d327fc0d58f5e4052f43c54c9Bobby Georgescu return mBucketId == MediaSetUtils.CAMERA_BUCKET_ID; 997eea4d3ac59aa88d327fc0d58f5e4052f43c54c9Bobby Georgescu } 1007eea4d3ac59aa88d327fc0d58f5e4052f43c54c9Bobby Georgescu 1017eea4d3ac59aa88d327fc0d58f5e4052f43c54c9Bobby Georgescu @Override 10284c220f10a643927c8a2126de8a755d8d7f7ec9eRay Chen public Uri getContentUri() { 10384c220f10a643927c8a2126de8a755d8d7f7ec9eRay Chen if (mIsImage) { 10484c220f10a643927c8a2126de8a755d8d7f7ec9eRay Chen return MediaStore.Images.Media.EXTERNAL_CONTENT_URI.buildUpon() 10584c220f10a643927c8a2126de8a755d8d7f7ec9eRay Chen .appendQueryParameter(LocalSource.KEY_BUCKET_ID, 10684c220f10a643927c8a2126de8a755d8d7f7ec9eRay Chen String.valueOf(mBucketId)).build(); 10784c220f10a643927c8a2126de8a755d8d7f7ec9eRay Chen } else { 10884c220f10a643927c8a2126de8a755d8d7f7ec9eRay Chen return MediaStore.Video.Media.EXTERNAL_CONTENT_URI.buildUpon() 10984c220f10a643927c8a2126de8a755d8d7f7ec9eRay Chen .appendQueryParameter(LocalSource.KEY_BUCKET_ID, 11084c220f10a643927c8a2126de8a755d8d7f7ec9eRay Chen String.valueOf(mBucketId)).build(); 11184c220f10a643927c8a2126de8a755d8d7f7ec9eRay Chen } 11284c220f10a643927c8a2126de8a755d8d7f7ec9eRay Chen } 11384c220f10a643927c8a2126de8a755d8d7f7ec9eRay Chen 11484c220f10a643927c8a2126de8a755d8d7f7ec9eRay Chen @Override 115f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public ArrayList<MediaItem> getMediaItem(int start, int count) { 116f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin DataManager dataManager = mApplication.getDataManager(); 117f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Uri uri = mBaseUri.buildUpon() 118f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin .appendQueryParameter("limit", start + "," + count).build(); 119f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin ArrayList<MediaItem> list = new ArrayList<MediaItem>(); 120f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin GalleryUtils.assertNotInRenderThread(); 121f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Cursor cursor = mResolver.query( 122f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin uri, mProjection, mWhereClause, 123f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin new String[]{String.valueOf(mBucketId)}, 124f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mOrderClause); 125f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (cursor == null) { 126f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Log.w(TAG, "query fail: " + uri); 127f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return list; 128f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 129f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 130f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin try { 131f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin while (cursor.moveToNext()) { 132f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int id = cursor.getInt(0); // _id must be in the first column 133f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Path childPath = mItemPath.getChild(id); 134f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin MediaItem item = loadOrUpdateItem(childPath, cursor, 135f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin dataManager, mApplication, mIsImage); 136f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin list.add(item); 137f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 138f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } finally { 139f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin cursor.close(); 140f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 141f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return list; 142f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 143f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 144f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static MediaItem loadOrUpdateItem(Path path, Cursor cursor, 145f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin DataManager dataManager, GalleryApp app, boolean isImage) { 146676d4762496eddae66930c6f8b0bae22a22b3ef6Owen Lin synchronized (DataManager.LOCK) { 147676d4762496eddae66930c6f8b0bae22a22b3ef6Owen Lin LocalMediaItem item = (LocalMediaItem) dataManager.peekMediaObject(path); 148676d4762496eddae66930c6f8b0bae22a22b3ef6Owen Lin if (item == null) { 149676d4762496eddae66930c6f8b0bae22a22b3ef6Owen Lin if (isImage) { 150676d4762496eddae66930c6f8b0bae22a22b3ef6Owen Lin item = new LocalImage(path, app, cursor); 151676d4762496eddae66930c6f8b0bae22a22b3ef6Owen Lin } else { 152676d4762496eddae66930c6f8b0bae22a22b3ef6Owen Lin item = new LocalVideo(path, app, cursor); 153676d4762496eddae66930c6f8b0bae22a22b3ef6Owen Lin } 154f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } else { 155676d4762496eddae66930c6f8b0bae22a22b3ef6Owen Lin item.updateContent(cursor); 156f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 157676d4762496eddae66930c6f8b0bae22a22b3ef6Owen Lin return item; 158f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 159f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 160f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 161f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // The pids array are sorted by the (path) id. 162f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public static MediaItem[] getMediaItemById( 163f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin GalleryApp application, boolean isImage, ArrayList<Integer> ids) { 164f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // get the lower and upper bound of (path) id 165f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin MediaItem[] result = new MediaItem[ids.size()]; 166f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (ids.isEmpty()) return result; 167f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int idLow = ids.get(0); 168f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int idHigh = ids.get(ids.size() - 1); 169f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 170f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // prepare the query parameters 171f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Uri baseUri; 172f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin String[] projection; 173f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Path itemPath; 174f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (isImage) { 175f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin baseUri = Images.Media.EXTERNAL_CONTENT_URI; 176f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin projection = LocalImage.PROJECTION; 177f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin itemPath = LocalImage.ITEM_PATH; 178f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } else { 179f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin baseUri = Video.Media.EXTERNAL_CONTENT_URI; 180f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin projection = LocalVideo.PROJECTION; 181f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin itemPath = LocalVideo.ITEM_PATH; 182f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 183f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 184f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin ContentResolver resolver = application.getContentResolver(); 185f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin DataManager dataManager = application.getDataManager(); 186f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Cursor cursor = resolver.query(baseUri, projection, "_id BETWEEN ? AND ?", 187f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin new String[]{String.valueOf(idLow), String.valueOf(idHigh)}, 188f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin "_id"); 189f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (cursor == null) { 190f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Log.w(TAG, "query fail" + baseUri); 191f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return result; 192f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 193f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin try { 194f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int n = ids.size(); 195f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int i = 0; 196f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 197f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin while (i < n && cursor.moveToNext()) { 198f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int id = cursor.getInt(0); // _id must be in the first column 199f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 200f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // Match id with the one on the ids list. 201f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (ids.get(i) > id) { 202f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin continue; 203f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 204f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 205f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin while (ids.get(i) < id) { 206f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (++i >= n) { 207f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return result; 208f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 209f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 210f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 211f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Path childPath = itemPath.getChild(id); 212f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin MediaItem item = loadOrUpdateItem(childPath, cursor, dataManager, 213f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin application, isImage); 214f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin result[i] = item; 215f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin ++i; 216f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 217f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return result; 218f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } finally { 219f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin cursor.close(); 220f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 221f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 222f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 223f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public static Cursor getItemCursor(ContentResolver resolver, Uri uri, 224f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin String[] projection, int id) { 225f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return resolver.query(uri, projection, "_id=?", 226f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin new String[]{String.valueOf(id)}, null); 227f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 228f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 229f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 230f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public int getMediaItemCount() { 231f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mCachedCount == INVALID_COUNT) { 232f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Cursor cursor = mResolver.query( 233f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mBaseUri, COUNT_PROJECTION, mWhereClause, 234f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin new String[]{String.valueOf(mBucketId)}, null); 235f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (cursor == null) { 236f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Log.w(TAG, "query fail"); 237f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return 0; 238f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 239f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin try { 240f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Utils.assertTrue(cursor.moveToNext()); 241f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mCachedCount = cursor.getInt(0); 242f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } finally { 243f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin cursor.close(); 244f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 245f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 246f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return mCachedCount; 247f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 248f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 249f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 250f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public String getName() { 251ef1e404cfa1227e309786675a6026dec842b5ab1Bobby Georgescu return getLocalizedName(mApplication.getResources(), mBucketId, mName); 252f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 253f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 254f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 255705dc819661cb8c8e839a04577b0641bd6caad53John Reck public long reload() { 256705dc819661cb8c8e839a04577b0641bd6caad53John Reck if (mNotifier.isDirty()) { 257705dc819661cb8c8e839a04577b0641bd6caad53John Reck mDataVersion = nextVersionNumber(); 258705dc819661cb8c8e839a04577b0641bd6caad53John Reck mCachedCount = INVALID_COUNT; 259705dc819661cb8c8e839a04577b0641bd6caad53John Reck } 260705dc819661cb8c8e839a04577b0641bd6caad53John Reck return mDataVersion; 261f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 262f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 263f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 264f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public int getSupportedOperations() { 265f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return SUPPORT_DELETE | SUPPORT_SHARE | SUPPORT_INFO; 266f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 267f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 268f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 269f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void delete() { 270f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin GalleryUtils.assertNotInRenderThread(); 271f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mResolver.delete(mBaseUri, mWhereClause, 272f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin new String[]{String.valueOf(mBucketId)}); 273f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 274f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 275f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 276f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public boolean isLeafAlbum() { 277f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return true; 278f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 2796caf221c4888f8632e8eb5b60b145bfca3557b3aChih-Chung Chang 2800addfc7f6342184a67cdd8b5cc3872c6a5c87e55Doris Liu public static String getLocalizedName(Resources res, int bucketId, 2816caf221c4888f8632e8eb5b60b145bfca3557b3aChih-Chung Chang String name) { 2826caf221c4888f8632e8eb5b60b145bfca3557b3aChih-Chung Chang if (bucketId == MediaSetUtils.CAMERA_BUCKET_ID) { 2836caf221c4888f8632e8eb5b60b145bfca3557b3aChih-Chung Chang return res.getString(R.string.folder_camera); 2846caf221c4888f8632e8eb5b60b145bfca3557b3aChih-Chung Chang } else if (bucketId == MediaSetUtils.DOWNLOAD_BUCKET_ID) { 2856caf221c4888f8632e8eb5b60b145bfca3557b3aChih-Chung Chang return res.getString(R.string.folder_download); 2866caf221c4888f8632e8eb5b60b145bfca3557b3aChih-Chung Chang } else if (bucketId == MediaSetUtils.IMPORTED_BUCKET_ID) { 2876caf221c4888f8632e8eb5b60b145bfca3557b3aChih-Chung Chang return res.getString(R.string.folder_imported); 2886caf221c4888f8632e8eb5b60b145bfca3557b3aChih-Chung Chang } else if (bucketId == MediaSetUtils.SNAPSHOT_BUCKET_ID) { 2896caf221c4888f8632e8eb5b60b145bfca3557b3aChih-Chung Chang return res.getString(R.string.folder_screenshot); 2900addfc7f6342184a67cdd8b5cc3872c6a5c87e55Doris Liu } else if (bucketId == MediaSetUtils.EDITED_ONLINE_PHOTOS_BUCKET_ID) { 2910addfc7f6342184a67cdd8b5cc3872c6a5c87e55Doris Liu return res.getString(R.string.folder_edited_online_photos); 2926caf221c4888f8632e8eb5b60b145bfca3557b3aChih-Chung Chang } else { 2936caf221c4888f8632e8eb5b60b145bfca3557b3aChih-Chung Chang return name; 2946caf221c4888f8632e8eb5b60b145bfca3557b3aChih-Chung Chang } 2956caf221c4888f8632e8eb5b60b145bfca3557b3aChih-Chung Chang } 296fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu 297fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu // Relative path is the absolute path minus external storage path 298fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu public static String getRelativePath(int bucketId) { 299fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu String relativePath = "/"; 300fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu if (bucketId == MediaSetUtils.CAMERA_BUCKET_ID) { 301fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu relativePath += BucketNames.CAMERA; 302fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu } else if (bucketId == MediaSetUtils.DOWNLOAD_BUCKET_ID) { 303fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu relativePath += BucketNames.DOWNLOAD; 304fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu } else if (bucketId == MediaSetUtils.IMPORTED_BUCKET_ID) { 305fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu relativePath += BucketNames.IMPORTED; 306fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu } else if (bucketId == MediaSetUtils.SNAPSHOT_BUCKET_ID) { 307fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu relativePath += BucketNames.SCREENSHOTS; 308fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu } else if (bucketId == MediaSetUtils.EDITED_ONLINE_PHOTOS_BUCKET_ID) { 309fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu relativePath += BucketNames.EDITED_ONLINE_PHOTOS; 310fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu } else { 311fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu // If the first few cases didn't hit the matching path, do a 312fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu // thorough search in the local directories. 313fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu File extStorage = Environment.getExternalStorageDirectory(); 314fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu String path = GalleryUtils.searchDirForPath(extStorage, bucketId); 315fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu if (path == null) { 316fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu Log.w(TAG, "Relative path for bucket id: " + bucketId + " is not found."); 317fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu relativePath = null; 318fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu } else { 319fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu relativePath = path.substring(extStorage.getAbsolutePath().length()); 320fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu } 321fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu } 322fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu return relativePath; 323fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu } 324fcf54601d45bfcef2fbeb911c46ff394e84d7011Doris Liu 325f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin} 326