@Override
  public void onLoadFinished(Loader<BitmapResult> loader, BitmapResult result) {
    // If we don't have a view, the fragment has been paused. We'll get the cursor again later.
    // If we're not added, the fragment has detached during the loading process. We no longer
    // need the result.
    if (getView() == null || !isAdded()) {
      return;
    }

    final Drawable data = result.getDrawable(getResources());

    final int id = loader.getId();
    switch (id) {
      case PhotoViewCallbacks.BITMAP_LOADER_THUMBNAIL:
        if (mDisplayThumbsFullScreen) {
          displayPhoto(result);
        } else {
          if (isPhotoBound()) {
            // There is need to do anything with the thumbnail
            // image, as the full size image is being shown.
            return;
          }

          if (data == null) {
            // no preview, show default
            mPhotoPreviewImage.setImageResource(R.drawable.default_image);
            mThumbnailShown = false;
          } else {
            // show preview
            mPhotoPreviewImage.setImageDrawable(data);
            mThumbnailShown = true;
          }
          mPhotoPreviewImage.setVisibility(View.VISIBLE);
          if (getResources().getBoolean(R.bool.force_thumbnail_no_scaling)) {
            mPhotoPreviewImage.setScaleType(ImageView.ScaleType.CENTER);
          }
          enableImageTransforms(false);
        }
        break;

      case PhotoViewCallbacks.BITMAP_LOADER_PHOTO:
        displayPhoto(result);
        break;
      default:
        break;
    }

    if (mProgressBarNeeded == false) {
      // Hide the progress bar as it isn't needed anymore.
      mPhotoProgressBar.setVisibility(View.GONE);
    }

    if (data != null) {
      mCallback.onNewPhotoLoaded(mPosition);
    }
    setViewVisibility();
  }
 private void displayPhoto(BitmapResult result) {
   if (result.status == BitmapResult.STATUS_EXCEPTION) {
     mProgressBarNeeded = false;
     mEmptyText.setText(R.string.failed);
     mEmptyText.setVisibility(View.VISIBLE);
     mCallback.onFragmentPhotoLoadComplete(this, false /* success */);
   } else {
     final Drawable data = result.getDrawable(getResources());
     bindPhoto(data);
     mCallback.onFragmentPhotoLoadComplete(this, true /* success */);
   }
 }
  /**
   * Create a bitmap from a local URI
   *
   * @param resolver The ContentResolver
   * @param uri The local URI
   * @param maxSize The maximum size (either width or height)
   * @return The new bitmap or null
   */
  public static BitmapResult createLocalBitmap(
      final ContentResolver resolver, final Uri uri, final int maxSize) {
    final BitmapResult result = new BitmapResult();
    final InputStreamFactory factory = createInputStreamFactory(resolver, uri);
    try {
      final Point bounds = getImageBounds(factory);
      if (bounds == null) {
        result.status = BitmapResult.STATUS_EXCEPTION;
        return result;
      }

      final BitmapFactory.Options opts = new BitmapFactory.Options();
      opts.inSampleSize = Math.max(bounds.x / maxSize, bounds.y / maxSize);
      result.bitmap = decodeStream(factory, null, opts);
      result.status = BitmapResult.STATUS_SUCCESS;
      return result;

    } catch (FileNotFoundException exception) {
      // Do nothing - the photo will appear to be missing
    } catch (IOException exception) {
      result.status = BitmapResult.STATUS_EXCEPTION;
    } catch (IllegalArgumentException exception) {
      // Do nothing - the photo will appear to be missing
    } catch (SecurityException exception) {
      result.status = BitmapResult.STATUS_EXCEPTION;
    }
    return result;
  }