11cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein/* 21cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein * Copyright (C) 2011 Google Inc. 31cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein * Licensed to The Android Open Source Project. 41cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein * 51cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein * Licensed under the Apache License, Version 2.0 (the "License"); 61cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein * you may not use this file except in compliance with the License. 71cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein * You may obtain a copy of the License at 81cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein * 91cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein * http://www.apache.org/licenses/LICENSE-2.0 101cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein * 111cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein * Unless required by applicable law or agreed to in writing, software 121cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein * distributed under the License is distributed on an "AS IS" BASIS, 131cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 141cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein * See the License for the specific language governing permissions and 151cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein * limitations under the License. 161cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein */ 171cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein 181cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sappersteinpackage com.android.ex.photo.loaders; 191cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein 201cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sappersteinimport android.content.AsyncTaskLoader; 211cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sappersteinimport android.content.ContentResolver; 221cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sappersteinimport android.content.Context; 231cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sappersteinimport android.graphics.Bitmap; 241cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sappersteinimport android.net.Uri; 254f38cc1673163848c7b843cb9d23b21945b0bf82Mark Weiimport android.util.DisplayMetrics; 261cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein 271cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sappersteinimport com.android.ex.photo.fragments.PhotoViewFragment; 281cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sappersteinimport com.android.ex.photo.util.ImageUtils; 291cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein 301cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein/** 311cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein * Loader for the bitmap of a photo. 321cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein */ 331cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sappersteinpublic class PhotoBitmapLoader extends AsyncTaskLoader<Bitmap> { 34a6729336171ef61950d5f585b0f39c013ae6dcbcAndrew Sapperstein private String mPhotoUri; 351cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein 361cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein private Bitmap mBitmap; 371cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein 381cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein public PhotoBitmapLoader(Context context, String photoUri) { 391cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein super(context); 401cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein mPhotoUri = photoUri; 411cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein } 421cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein 43a6729336171ef61950d5f585b0f39c013ae6dcbcAndrew Sapperstein public void setPhotoUri(String photoUri) { 44a6729336171ef61950d5f585b0f39c013ae6dcbcAndrew Sapperstein mPhotoUri = photoUri; 45a6729336171ef61950d5f585b0f39c013ae6dcbcAndrew Sapperstein } 46a6729336171ef61950d5f585b0f39c013ae6dcbcAndrew Sapperstein 471cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein @Override 481cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein public Bitmap loadInBackground() { 491cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein Context context = getContext(); 501cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein 511cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein if (context != null && mPhotoUri != null) { 521cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein final ContentResolver resolver = context.getContentResolver(); 534f38cc1673163848c7b843cb9d23b21945b0bf82Mark Wei Bitmap bitmap = ImageUtils.createLocalBitmap(resolver, Uri.parse(mPhotoUri), 541cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein PhotoViewFragment.sPhotoSize); 55a7e22413eb860a1d9ffb46221c63e29ba7330ff5Mark Wei if (bitmap != null) { 56a7e22413eb860a1d9ffb46221c63e29ba7330ff5Mark Wei bitmap.setDensity(DisplayMetrics.DENSITY_MEDIUM); 57a7e22413eb860a1d9ffb46221c63e29ba7330ff5Mark Wei } 584f38cc1673163848c7b843cb9d23b21945b0bf82Mark Wei return bitmap; 591cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein } 601cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein 611cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein return null; 621cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein } 631cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein 641cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein /** 651cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein * Called when there is new data to deliver to the client. The 661cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein * super class will take care of delivering it; the implementation 671cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein * here just adds a little more logic. 681cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein */ 691cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein @Override 701cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein public void deliverResult(Bitmap bitmap) { 711cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein if (isReset()) { 721cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein // An async query came in while the loader is stopped. We 731cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein // don't need the result. 741cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein if (bitmap != null) { 751cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein onReleaseResources(bitmap); 761cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein } 771cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein } 781cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein Bitmap oldBitmap = mBitmap; 791cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein mBitmap = bitmap; 801cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein 811cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein if (isStarted()) { 821cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein // If the Loader is currently started, we can immediately 831cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein // deliver its results. 841cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein super.deliverResult(bitmap); 851cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein } 861cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein 871cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein // At this point we can release the resources associated with 881cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein // 'oldBitmap' if needed; now that the new result is delivered we 891cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein // know that it is no longer in use. 901cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein if (oldBitmap != null && oldBitmap != bitmap && !oldBitmap.isRecycled()) { 911cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein onReleaseResources(oldBitmap); 921cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein } 931cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein } 941cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein 951cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein /** 961cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein * Handles a request to start the Loader. 971cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein */ 981cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein @Override 991cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein protected void onStartLoading() { 1001cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein if (mBitmap != null) { 1011cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein // If we currently have a result available, deliver it 1021cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein // immediately. 1031cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein deliverResult(mBitmap); 1041cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein } 1051cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein 1061cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein if (takeContentChanged() || mBitmap == null) { 1071cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein // If the data has changed since the last time it was loaded 1081cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein // or is not currently available, start a load. 1091cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein forceLoad(); 1101cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein } 1111cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein } 1121cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein 1131cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein /** 1141cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein * Handles a request to stop the Loader. 1151cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein */ 1161cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein @Override protected void onStopLoading() { 1171cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein // Attempt to cancel the current load task if possible. 1181cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein cancelLoad(); 1191cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein } 1201cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein 1211cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein /** 1221cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein * Handles a request to cancel a load. 1231cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein */ 1241cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein @Override 1251cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein public void onCanceled(Bitmap bitmap) { 1261cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein super.onCanceled(bitmap); 1271cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein 1281cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein // At this point we can release the resources associated with 'bitmap' 1291cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein // if needed. 1301cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein onReleaseResources(bitmap); 1311cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein } 1321cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein 1331cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein /** 1341cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein * Handles a request to completely reset the Loader. 1351cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein */ 1361cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein @Override 1371cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein protected void onReset() { 1381cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein super.onReset(); 1391cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein 1401cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein // Ensure the loader is stopped 1411cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein onStopLoading(); 1421cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein 1431cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein // At this point we can release the resources associated with 'bitmap' 1441cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein // if needed. 1451cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein if (mBitmap != null) { 1461cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein onReleaseResources(mBitmap); 1471cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein mBitmap = null; 1481cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein } 1491cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein } 1501cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein 1511cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein /** 1521cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein * Helper function to take care of releasing resources associated 1531cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein * with an actively loaded data set. 1541cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein */ 1551cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein protected void onReleaseResources(Bitmap bitmap) { 1561cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein if (bitmap != null && !bitmap.isRecycled()) { 1571cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein bitmap.recycle(); 1581cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein } 1591cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein } 1601cc4b2144a45abb495c8b14f6cfc5a10fb5e8ba8Andrew Sapperstein} 161