1c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wren/* 2c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wren * Copyright (C) 2012 The Android Open Source Project 3c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wren * 4c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wren * Licensed under the Apache License, Version 2.0 (the "License"); 5c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wren * you may not use this file except in compliance with the License. 6c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wren * You may obtain a copy of the License at 7c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wren * 8c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wren * http://www.apache.org/licenses/LICENSE-2.0 9c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wren * 10c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wren * Unless required by applicable law or agreed to in writing, software 11c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wren * distributed under the License is distributed on an "AS IS" BASIS, 12c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wren * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wren * See the License for the specific language governing permissions and 14c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wren * limitations under the License. 15c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wren */ 16c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wrenpackage com.android.dreams.phototable; 17c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wren 18c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wrenimport android.content.Context; 19d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wrenimport android.content.SharedPreferences; 20c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wrenimport android.database.Cursor; 21729f5231bf95ec7946fc4c510d44db303b07614dChris Wrenimport android.net.Uri; 22c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wrenimport android.provider.MediaStore; 23c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wren 24c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wrenimport java.io.FileInputStream; 2583fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wrenimport java.io.InputStream; 2683fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wrenimport java.util.Collection; 27d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wrenimport java.util.HashMap; 28c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wrenimport java.util.LinkedList; 29d9b659aa5dfa4a3af96582ae49ba9ae145854a84Chris Wrenimport java.util.Set; 30c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wren 31c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wren/** 3283fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren * Loads images from the local store. 33c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wren */ 3488d80f4471c900628e2cb6eef23029b99af48e09Chris Wrenpublic class LocalSource extends CursorPhotoSource { 35c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wren private static final String TAG = "PhotoTable.LocalSource"; 36c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wren 37e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren private final String mUnknownAlbumName; 38e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren private final String mLocalSourceName; 39d9b659aa5dfa4a3af96582ae49ba9ae145854a84Chris Wren private Set<String> mFoundAlbumIds; 40bed703ef28f013639db3cd7a6b8a6e94d61075daChris Wren private int mLastPosition; 41c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wren 42d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren public LocalSource(Context context, SharedPreferences settings) { 43d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren super(context, settings); 44e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren mLocalSourceName = mResources.getString(R.string.local_source_name, "Photos on Device"); 45e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren mUnknownAlbumName = mResources.getString(R.string.unknown_album_name, "Unknown"); 4683fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren mSourceName = TAG; 47bed703ef28f013639db3cd7a6b8a6e94d61075daChris Wren mLastPosition = INVALID; 48c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wren fillQueue(); 49c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wren } 50c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wren 51d9b659aa5dfa4a3af96582ae49ba9ae145854a84Chris Wren private Set<String> getFoundAlbums() { 52d9b659aa5dfa4a3af96582ae49ba9ae145854a84Chris Wren if (mFoundAlbumIds == null) { 53d9b659aa5dfa4a3af96582ae49ba9ae145854a84Chris Wren findAlbums(); 54d9b659aa5dfa4a3af96582ae49ba9ae145854a84Chris Wren } 55d9b659aa5dfa4a3af96582ae49ba9ae145854a84Chris Wren return mFoundAlbumIds; 56d9b659aa5dfa4a3af96582ae49ba9ae145854a84Chris Wren } 57d9b659aa5dfa4a3af96582ae49ba9ae145854a84Chris Wren 5883fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren @Override 59d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren public Collection<AlbumData> findAlbums() { 60d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren log(TAG, "finding albums"); 61d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren HashMap<String, AlbumData> foundAlbums = new HashMap<String, AlbumData>(); 62729f5231bf95ec7946fc4c510d44db303b07614dChris Wren findAlbums(false, foundAlbums); 63729f5231bf95ec7946fc4c510d44db303b07614dChris Wren findAlbums(true, foundAlbums); 64d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren 65729f5231bf95ec7946fc4c510d44db303b07614dChris Wren log(TAG, "found " + foundAlbums.size() + " items."); 66729f5231bf95ec7946fc4c510d44db303b07614dChris Wren mFoundAlbumIds = foundAlbums.keySet(); 67729f5231bf95ec7946fc4c510d44db303b07614dChris Wren return foundAlbums.values(); 68729f5231bf95ec7946fc4c510d44db303b07614dChris Wren } 69729f5231bf95ec7946fc4c510d44db303b07614dChris Wren 70729f5231bf95ec7946fc4c510d44db303b07614dChris Wren public void findAlbums(boolean internal, HashMap<String, AlbumData> foundAlbums) { 71729f5231bf95ec7946fc4c510d44db303b07614dChris Wren Uri uri = internal ? MediaStore.Images.Media.INTERNAL_CONTENT_URI 72729f5231bf95ec7946fc4c510d44db303b07614dChris Wren : MediaStore.Images.Media.EXTERNAL_CONTENT_URI; 73d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren String[] projection = {MediaStore.Images.Media.DATA, MediaStore.Images.Media.BUCKET_ID, 74d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren MediaStore.Images.Media.BUCKET_DISPLAY_NAME, MediaStore.Images.Media.DATE_TAKEN}; 75d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren // This is a horrible hack that closes the where clause and injects a grouping clause. 76729f5231bf95ec7946fc4c510d44db303b07614dChris Wren Cursor cursor = mResolver.query(uri, projection, null, null, null); 77d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren if (cursor != null) { 78bed703ef28f013639db3cd7a6b8a6e94d61075daChris Wren cursor.moveToPosition(-1); 79d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren 80d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren int dataIndex = cursor.getColumnIndex(MediaStore.Images.Media.DATA); 81d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren int bucketIndex = cursor.getColumnIndex(MediaStore.Images.Media.BUCKET_ID); 82d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren int nameIndex = cursor.getColumnIndex(MediaStore.Images.Media.BUCKET_DISPLAY_NAME); 83d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren int updatedIndex = cursor.getColumnIndex(MediaStore.Images.Media.DATE_TAKEN); 84d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren 85d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren if (bucketIndex < 0) { 86d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren log(TAG, "can't find the ID column!"); 87d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren } else { 88bed703ef28f013639db3cd7a6b8a6e94d61075daChris Wren while (cursor.moveToNext()) { 89729f5231bf95ec7946fc4c510d44db303b07614dChris Wren String id = constructId(internal, cursor.getString(bucketIndex)); 90d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren AlbumData data = foundAlbums.get(id); 91d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren if (foundAlbums.get(id) == null) { 92d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren data = new AlbumData(); 93d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren data.id = id; 94e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren data.account = mLocalSourceName; 95d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren 96d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren if (dataIndex >= 0) { 97d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren data.thumbnailUrl = cursor.getString(dataIndex); 98d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren } 99d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren 100d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren if (nameIndex >= 0) { 101d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren data.title = cursor.getString(nameIndex); 102d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren } else { 103e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren data.title = mUnknownAlbumName; 104d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren } 105d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren 106d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren log(TAG, data.title + " found"); 107d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren foundAlbums.put(id, data); 108d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren } 109d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren if (updatedIndex >= 0) { 110d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren long updated = cursor.getLong(updatedIndex); 111d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren data.updated = (data.updated == 0 ? 112d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren updated : 113d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren Math.min(data.updated, updated)); 114d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren } 115d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren } 116d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren } 117d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren cursor.close(); 118d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren } 119729f5231bf95ec7946fc4c510d44db303b07614dChris Wren } 120729f5231bf95ec7946fc4c510d44db303b07614dChris Wren 121729f5231bf95ec7946fc4c510d44db303b07614dChris Wren public static String constructId(boolean internal, String bucketId) { 122729f5231bf95ec7946fc4c510d44db303b07614dChris Wren return TAG + ":" + bucketId + (internal ? ":i" : ""); 123d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren } 124d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren 125d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren @Override 12688d80f4471c900628e2cb6eef23029b99af48e09Chris Wren protected void openCursor(ImageData data) { 12788d80f4471c900628e2cb6eef23029b99af48e09Chris Wren log(TAG, "opening single album"); 12888d80f4471c900628e2cb6eef23029b99af48e09Chris Wren 12988d80f4471c900628e2cb6eef23029b99af48e09Chris Wren String[] projection = {MediaStore.Images.Media.DATA, MediaStore.Images.Media.ORIENTATION, 13088d80f4471c900628e2cb6eef23029b99af48e09Chris Wren MediaStore.Images.Media.BUCKET_ID, MediaStore.Images.Media.BUCKET_DISPLAY_NAME}; 13188d80f4471c900628e2cb6eef23029b99af48e09Chris Wren String selection = MediaStore.Images.Media.BUCKET_ID + " = '" + data.albumId + "'"; 13288d80f4471c900628e2cb6eef23029b99af48e09Chris Wren 133729f5231bf95ec7946fc4c510d44db303b07614dChris Wren data.cursor = mResolver.query(data.uri, projection, selection, null, null); 13488d80f4471c900628e2cb6eef23029b99af48e09Chris Wren } 13588d80f4471c900628e2cb6eef23029b99af48e09Chris Wren 13688d80f4471c900628e2cb6eef23029b99af48e09Chris Wren @Override 13788d80f4471c900628e2cb6eef23029b99af48e09Chris Wren protected void findPosition(ImageData data) { 13888d80f4471c900628e2cb6eef23029b99af48e09Chris Wren if (data.position == -1) { 13988d80f4471c900628e2cb6eef23029b99af48e09Chris Wren if (data.cursor == null) { 14088d80f4471c900628e2cb6eef23029b99af48e09Chris Wren openCursor(data); 14188d80f4471c900628e2cb6eef23029b99af48e09Chris Wren } 14288d80f4471c900628e2cb6eef23029b99af48e09Chris Wren if (data.cursor != null) { 14388d80f4471c900628e2cb6eef23029b99af48e09Chris Wren int dataIndex = data.cursor.getColumnIndex(MediaStore.Images.Media.DATA); 14488d80f4471c900628e2cb6eef23029b99af48e09Chris Wren data.cursor.moveToPosition(-1); 14588d80f4471c900628e2cb6eef23029b99af48e09Chris Wren while (data.position == -1 && data.cursor.moveToNext()) { 14688d80f4471c900628e2cb6eef23029b99af48e09Chris Wren String url = data.cursor.getString(dataIndex); 14788d80f4471c900628e2cb6eef23029b99af48e09Chris Wren if (url != null && url.equals(data.url)) { 14888d80f4471c900628e2cb6eef23029b99af48e09Chris Wren data.position = data.cursor.getPosition(); 14988d80f4471c900628e2cb6eef23029b99af48e09Chris Wren } 15088d80f4471c900628e2cb6eef23029b99af48e09Chris Wren } 15188d80f4471c900628e2cb6eef23029b99af48e09Chris Wren if (data.position == -1) { 15288d80f4471c900628e2cb6eef23029b99af48e09Chris Wren // oops! The image isn't in this album. How did we get here? 15388d80f4471c900628e2cb6eef23029b99af48e09Chris Wren data.position = INVALID; 15488d80f4471c900628e2cb6eef23029b99af48e09Chris Wren } 15588d80f4471c900628e2cb6eef23029b99af48e09Chris Wren } 15688d80f4471c900628e2cb6eef23029b99af48e09Chris Wren } 15788d80f4471c900628e2cb6eef23029b99af48e09Chris Wren } 15888d80f4471c900628e2cb6eef23029b99af48e09Chris Wren 15988d80f4471c900628e2cb6eef23029b99af48e09Chris Wren @Override 16088d80f4471c900628e2cb6eef23029b99af48e09Chris Wren protected ImageData unpackImageData(Cursor cursor, ImageData data) { 16188d80f4471c900628e2cb6eef23029b99af48e09Chris Wren if (data == null) { 16288d80f4471c900628e2cb6eef23029b99af48e09Chris Wren data = new ImageData(); 16388d80f4471c900628e2cb6eef23029b99af48e09Chris Wren } 16488d80f4471c900628e2cb6eef23029b99af48e09Chris Wren int dataIndex = cursor.getColumnIndex(MediaStore.Images.Media.DATA); 16588d80f4471c900628e2cb6eef23029b99af48e09Chris Wren int orientationIndex = cursor.getColumnIndex(MediaStore.Images.Media.ORIENTATION); 16688d80f4471c900628e2cb6eef23029b99af48e09Chris Wren int bucketIndex = cursor.getColumnIndex(MediaStore.Images.Media.BUCKET_ID); 16788d80f4471c900628e2cb6eef23029b99af48e09Chris Wren 16888d80f4471c900628e2cb6eef23029b99af48e09Chris Wren data.url = cursor.getString(dataIndex); 16988d80f4471c900628e2cb6eef23029b99af48e09Chris Wren data.albumId = cursor.getString(bucketIndex); 17088d80f4471c900628e2cb6eef23029b99af48e09Chris Wren data.position = UNINITIALIZED; 17188d80f4471c900628e2cb6eef23029b99af48e09Chris Wren data.cursor = null; 17288d80f4471c900628e2cb6eef23029b99af48e09Chris Wren data.orientation = cursor.getInt(orientationIndex); 17388d80f4471c900628e2cb6eef23029b99af48e09Chris Wren 17488d80f4471c900628e2cb6eef23029b99af48e09Chris Wren return data; 17588d80f4471c900628e2cb6eef23029b99af48e09Chris Wren } 17688d80f4471c900628e2cb6eef23029b99af48e09Chris Wren 17788d80f4471c900628e2cb6eef23029b99af48e09Chris Wren @Override 17883fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren protected Collection<ImageData> findImages(int howMany) { 17983fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren log(TAG, "finding images"); 18083fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren LinkedList<ImageData> foundImages = new LinkedList<ImageData>(); 181729f5231bf95ec7946fc4c510d44db303b07614dChris Wren boolean internalFirst = mRNG.nextInt(2) == 0; // filp a coin to be fair 182729f5231bf95ec7946fc4c510d44db303b07614dChris Wren findImages(internalFirst, howMany, foundImages); 183729f5231bf95ec7946fc4c510d44db303b07614dChris Wren findImages(!internalFirst, howMany - foundImages.size(), foundImages); 184729f5231bf95ec7946fc4c510d44db303b07614dChris Wren log(TAG, "found " + foundImages.size() + " items."); 185729f5231bf95ec7946fc4c510d44db303b07614dChris Wren return foundImages; 186729f5231bf95ec7946fc4c510d44db303b07614dChris Wren } 18783fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren 188729f5231bf95ec7946fc4c510d44db303b07614dChris Wren protected void findImages(boolean internal, int howMany, LinkedList<ImageData> foundImages ) { 189729f5231bf95ec7946fc4c510d44db303b07614dChris Wren Uri uri = internal ? MediaStore.Images.Media.INTERNAL_CONTENT_URI 190729f5231bf95ec7946fc4c510d44db303b07614dChris Wren : MediaStore.Images.Media.EXTERNAL_CONTENT_URI; 19183fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren String[] projection = {MediaStore.Images.Media.DATA, MediaStore.Images.Media.ORIENTATION, 19283fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren MediaStore.Images.Media.BUCKET_ID, MediaStore.Images.Media.BUCKET_DISPLAY_NAME}; 19383fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren String selection = ""; 194d9b659aa5dfa4a3af96582ae49ba9ae145854a84Chris Wren for (String id : getFoundAlbums()) { 195729f5231bf95ec7946fc4c510d44db303b07614dChris Wren if (isInternalId(id) == internal && mSettings.isAlbumEnabled(id)) { 196d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren String[] parts = id.split(":"); 197d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren if (parts.length > 1) { 198d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren if (selection.length() > 0) { 199d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren selection += " OR "; 200d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren } 201d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren selection += MediaStore.Images.Media.BUCKET_ID + " = '" + parts[1] + "'"; 202d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren } 20383fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren } 20483fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren } 205d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren if (selection.isEmpty()) { 206729f5231bf95ec7946fc4c510d44db303b07614dChris Wren return; 207d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren } 208729f5231bf95ec7946fc4c510d44db303b07614dChris Wren Cursor cursor = mResolver.query(uri, projection, selection, null, null); 209c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wren if (cursor != null) { 21088d80f4471c900628e2cb6eef23029b99af48e09Chris Wren int dataIndex = cursor.getColumnIndex(MediaStore.Images.Media.DATA); 21188d80f4471c900628e2cb6eef23029b99af48e09Chris Wren 212bed703ef28f013639db3cd7a6b8a6e94d61075daChris Wren if (cursor.getCount() > howMany && mLastPosition == INVALID) { 213bed703ef28f013639db3cd7a6b8a6e94d61075daChris Wren mLastPosition = pickRandomStart(cursor.getCount(), howMany); 214c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wren } 215bed703ef28f013639db3cd7a6b8a6e94d61075daChris Wren cursor.moveToPosition(mLastPosition); 216c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wren 217c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wren if (dataIndex < 0) { 21883fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren log(TAG, "can't find the DATA column!"); 219c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wren } else { 220bed703ef28f013639db3cd7a6b8a6e94d61075daChris Wren while (foundImages.size() < howMany && cursor.moveToNext()) { 22188d80f4471c900628e2cb6eef23029b99af48e09Chris Wren ImageData data = unpackImageData(cursor, null); 222729f5231bf95ec7946fc4c510d44db303b07614dChris Wren data.uri = uri; 22383fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren foundImages.offer(data); 224bed703ef28f013639db3cd7a6b8a6e94d61075daChris Wren mLastPosition = cursor.getPosition(); 225c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wren } 226c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wren if (cursor.isAfterLast()) { 227bed703ef28f013639db3cd7a6b8a6e94d61075daChris Wren mLastPosition = -1; 228bed703ef28f013639db3cd7a6b8a6e94d61075daChris Wren } 229bed703ef28f013639db3cd7a6b8a6e94d61075daChris Wren if (cursor.isBeforeFirst()) { 230bed703ef28f013639db3cd7a6b8a6e94d61075daChris Wren mLastPosition = INVALID; 231c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wren } 232c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wren } 23383fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren 234c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wren cursor.close(); 235c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wren } 236729f5231bf95ec7946fc4c510d44db303b07614dChris Wren } 237729f5231bf95ec7946fc4c510d44db303b07614dChris Wren 238729f5231bf95ec7946fc4c510d44db303b07614dChris Wren private boolean isInternalId(String id) { 239729f5231bf95ec7946fc4c510d44db303b07614dChris Wren return id.endsWith("i"); 240c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wren } 241c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wren 24283fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren @Override 243c6bebae5e07c0108294d05e33fbace209d2f9b0dChris Wren protected InputStream getStream(ImageData data, int longSide) { 24483fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren FileInputStream fis = null; 24583fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren try { 24683fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren log(TAG, "opening:" + data.url); 24783fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren fis = new FileInputStream(data.url); 24883fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren } catch (Exception ex) { 24983fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren log(TAG, ex.toString()); 25083fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren fis = null; 251c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wren } 252c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wren 25383fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren return (InputStream) fis; 254c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wren } 255c8ca07eb52a54efe327d024dc542e0a7f8849bfbChris Wren} 25688d80f4471c900628e2cb6eef23029b99af48e09Chris Wren 257