summaryrefslogtreecommitdiffstats
path: root/photoviewer
diff options
context:
space:
mode:
authorAdam Copp <adamcopp@google.com>2012-08-22 03:22:45 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2012-08-22 03:22:45 -0700
commit34e9a4486aeeaa104f534629a0bea2fccd2bc88a (patch)
tree3935d5c0939a5635c00996c1a07b14602d503516 /photoviewer
parent5f53c9840779cbe038c2aea348a3b0ff0c6817f5 (diff)
parentd7ae9863e34c878985d35133c3b56bee481ec4b1 (diff)
downloadandroid_frameworks_ex-34e9a4486aeeaa104f534629a0bea2fccd2bc88a.tar.gz
android_frameworks_ex-34e9a4486aeeaa104f534629a0bea2fccd2bc88a.tar.bz2
android_frameworks_ex-34e9a4486aeeaa104f534629a0bea2fccd2bc88a.zip
Merge "Add HTTP uri handling & fetch thumbnail first"
Diffstat (limited to 'photoviewer')
-rw-r--r--photoviewer/.gitignore8
-rw-r--r--photoviewer/src/com/android/ex/photo/PhotoViewActivity.java11
-rw-r--r--photoviewer/src/com/android/ex/photo/fragments/PhotoViewFragment.java8
-rw-r--r--photoviewer/src/com/android/ex/photo/util/ImageUtils.java362
4 files changed, 214 insertions, 175 deletions
diff --git a/photoviewer/.gitignore b/photoviewer/.gitignore
new file mode 100644
index 0000000..ff7ef7d
--- /dev/null
+++ b/photoviewer/.gitignore
@@ -0,0 +1,8 @@
+*~
+*.bak
+*.class
+bin/
+gen/
+*.properties
+.classpath
+.project
diff --git a/photoviewer/src/com/android/ex/photo/PhotoViewActivity.java b/photoviewer/src/com/android/ex/photo/PhotoViewActivity.java
index 2e54569..c15bc1a 100644
--- a/photoviewer/src/com/android/ex/photo/PhotoViewActivity.java
+++ b/photoviewer/src/com/android/ex/photo/PhotoViewActivity.java
@@ -31,6 +31,7 @@ import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.view.ViewPager.OnPageChangeListener;
+import android.view.MenuItem;
import android.view.View;
import com.android.ex.photo.PhotoViewPager.InterceptType;
@@ -237,6 +238,16 @@ public class PhotoViewActivity extends Activity implements
outState.putBoolean(STATE_FULLSCREEN_KEY, mFullScreen);
}
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ finish();
+ default:
+ return super.onOptionsItemSelected(item);
+ }
+ }
+
public void addScreenListener(OnScreenListener listener) {
mScreenListeners.add(listener);
}
diff --git a/photoviewer/src/com/android/ex/photo/fragments/PhotoViewFragment.java b/photoviewer/src/com/android/ex/photo/fragments/PhotoViewFragment.java
index 97ea3b8..4da6ab0 100644
--- a/photoviewer/src/com/android/ex/photo/fragments/PhotoViewFragment.java
+++ b/photoviewer/src/com/android/ex/photo/fragments/PhotoViewFragment.java
@@ -204,7 +204,7 @@ public class PhotoViewFragment extends Fragment implements
mCallback.addScreenListener(this);
mCallback.addCursorListener(this);
- getLoaderManager().initLoader(LOADER_ID_PHOTO, null, this);
+ getLoaderManager().initLoader(LOADER_ID_THUMBNAIL, null, this);
super.onResume();
}
@@ -284,10 +284,8 @@ public class PhotoViewFragment extends Fragment implements
mProgressBarNeeded = false;
} else {
- mPhotoPreviewImage.setVisibility(View.VISIBLE);
- mPhotoPreviewImage.setImageBitmap(data);
-
- mProgressBarNeeded = false;
+ bindPhoto(data);
+ getLoaderManager().initLoader(LOADER_ID_PHOTO, null, this);
}
break;
default:
diff --git a/photoviewer/src/com/android/ex/photo/util/ImageUtils.java b/photoviewer/src/com/android/ex/photo/util/ImageUtils.java
index 8564457..501356e 100644
--- a/photoviewer/src/com/android/ex/photo/util/ImageUtils.java
+++ b/photoviewer/src/com/android/ex/photo/util/ImageUtils.java
@@ -1,175 +1,197 @@
-/*
- * Copyright (C) 2011 Google Inc.
- * Licensed to The Android Open Source Project.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ex.photo.util;
-
-import android.content.ContentResolver;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.net.Uri;
-import android.os.Build;
-import android.util.Log;
-
-import com.android.ex.photo.PhotoViewActivity;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * Image utilities
- */
-public class ImageUtils {
- // Logging
- private static final String TAG = "ImageUtils";
-
- /** Minimum class memory class to use full-res photos */
- private final static long MIN_NORMAL_CLASS = 32;
- /** Minimum class memory class to use small photos */
- private final static long MIN_SMALL_CLASS = 24;
-
- public static enum ImageSize {
- EXTRA_SMALL,
- SMALL,
- NORMAL,
- }
-
- public static final ImageSize sUseImageSize;
- static {
- // On HC and beyond, assume devices are more capable
- if (Build.VERSION.SDK_INT >= 11) {
- sUseImageSize = ImageSize.NORMAL;
- } else {
- if (PhotoViewActivity.sMemoryClass >= MIN_NORMAL_CLASS) {
- // We have plenty of memory; use full sized photos
- sUseImageSize = ImageSize.NORMAL;
- } else if (PhotoViewActivity.sMemoryClass >= MIN_SMALL_CLASS) {
- // We have slight less memory; use smaller sized photos
- sUseImageSize = ImageSize.SMALL;
- } else {
- // We have little memory; use very small sized photos
- sUseImageSize = ImageSize.EXTRA_SMALL;
- }
- }
- }
-
- /**
- * @return true if the MimeType type is image
- */
- public static boolean isImageMimeType(String mimeType) {
- return mimeType != null && mimeType.startsWith("image/");
- }
-
- /**
- * 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
- */
- public static Bitmap createLocalBitmap(ContentResolver resolver, Uri uri, int maxSize) {
- InputStream inputStream = null;
- try {
- final BitmapFactory.Options opts = new BitmapFactory.Options();
- final Point bounds = getImageBounds(resolver, uri);
-
- inputStream = resolver.openInputStream(uri);
- opts.inSampleSize = Math.max(bounds.x / maxSize, bounds.y / maxSize);
-
- final Bitmap decodedBitmap = decodeStream(inputStream, null, opts);
-
- // Correct thumbnail orientation as necessary
+/*
+ * Copyright (C) 2011 Google Inc.
+ * Licensed to The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ex.photo.util;
+
+import android.content.ContentResolver;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.net.Uri;
+import android.os.Build;
+import android.util.Log;
+
+import com.android.ex.photo.PhotoViewActivity;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+
+/**
+ * Image utilities
+ */
+public class ImageUtils {
+ // Logging
+ private static final String TAG = "ImageUtils";
+
+ /** Minimum class memory class to use full-res photos */
+ private final static long MIN_NORMAL_CLASS = 32;
+ /** Minimum class memory class to use small photos */
+ private final static long MIN_SMALL_CLASS = 24;
+
+ public static enum ImageSize {
+ EXTRA_SMALL,
+ SMALL,
+ NORMAL,
+ }
+
+ public static final ImageSize sUseImageSize;
+ static {
+ // On HC and beyond, assume devices are more capable
+ if (Build.VERSION.SDK_INT >= 11) {
+ sUseImageSize = ImageSize.NORMAL;
+ } else {
+ if (PhotoViewActivity.sMemoryClass >= MIN_NORMAL_CLASS) {
+ // We have plenty of memory; use full sized photos
+ sUseImageSize = ImageSize.NORMAL;
+ } else if (PhotoViewActivity.sMemoryClass >= MIN_SMALL_CLASS) {
+ // We have slight less memory; use smaller sized photos
+ sUseImageSize = ImageSize.SMALL;
+ } else {
+ // We have little memory; use very small sized photos
+ sUseImageSize = ImageSize.EXTRA_SMALL;
+ }
+ }
+ }
+
+ /**
+ * @return true if the MimeType type is image
+ */
+ public static boolean isImageMimeType(String mimeType) {
+ return mimeType != null && mimeType.startsWith("image/");
+ }
+
+ /**
+ * 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
+ */
+ public static Bitmap createLocalBitmap(ContentResolver resolver, Uri uri, int maxSize) {
+ // TODO: make this method not download the image for both getImageBounds and decodeStream
+ InputStream inputStream = null;
+ try {
+ final BitmapFactory.Options opts = new BitmapFactory.Options();
+ final Point bounds = getImageBounds(resolver, uri);
+
+ inputStream = openInputStream(resolver, uri);
+ opts.inSampleSize = Math.max(bounds.x / maxSize, bounds.y / maxSize);
+
+ final Bitmap decodedBitmap = decodeStream(inputStream, null, opts);
+
+ // Correct thumbnail orientation as necessary
// TODO: Fix rotation if it's actually a problem
//return rotateBitmap(resolver, uri, decodedBitmap);
return decodedBitmap;
-
- } catch (FileNotFoundException exception) {
- // Do nothing - the photo will appear to be missing
- } catch (IOException exception) {
- // Do nothing - the photo will appear to be missing
+
+ } catch (FileNotFoundException exception) {
+ // Do nothing - the photo will appear to be missing
+ } catch (IOException exception) {
+ // Do nothing - the photo will appear to be missing
} catch (IllegalArgumentException exception) {
// Do nothing - the photo will appear to be missing
- } finally {
- try {
- if (inputStream != null) {
- inputStream.close();
- }
- } catch (IOException ignore) {
- }
- }
- return null;
- }
-
- /**
- * Wrapper around {@link BitmapFactory#decodeStream(InputStream, Rect,
- * BitmapFactory.Options)} that returns {@code null} on {@link
- * OutOfMemoryError}.
- *
- * @param is The input stream that holds the raw data to be decoded into a
- * bitmap.
- * @param outPadding If not null, return the padding rect for the bitmap if
- * it exists, otherwise set padding to [-1,-1,-1,-1]. If
- * no bitmap is returned (null) then padding is
- * unchanged.
- * @param opts null-ok; Options that control downsampling and whether the
- * image should be completely decoded, or just is size returned.
- * @return The decoded bitmap, or null if the image data could not be
- * decoded, or, if opts is non-null, if opts requested only the
- * size be returned (in opts.outWidth and opts.outHeight)
- */
- public static Bitmap decodeStream(InputStream is, Rect outPadding, BitmapFactory.Options opts) {
- try {
- return BitmapFactory.decodeStream(is, outPadding, opts);
- } catch (OutOfMemoryError oome) {
- Log.e(TAG, "ImageUtils#decodeStream(InputStream, Rect, Options) threw an OOME", oome);
- return null;
- }
- }
-
- /**
- * Gets the image bounds
- *
- * @param resolver The ContentResolver
- * @param uri The uri
- *
- * @return The image bounds
- */
- private static Point getImageBounds(ContentResolver resolver, Uri uri)
- throws IOException {
- final BitmapFactory.Options opts = new BitmapFactory.Options();
- InputStream inputStream = null;
-
- try {
- opts.inJustDecodeBounds = true;
- inputStream = resolver.openInputStream(uri);
- decodeStream(inputStream, null, opts);
-
- return new Point(opts.outWidth, opts.outHeight);
- } finally {
- try {
- if (inputStream != null) {
- inputStream.close();
- }
- } catch (IOException ignore) {
- }
- }
- }
-}
+ } finally {
+ try {
+ if (inputStream != null) {
+ inputStream.close();
+ }
+ } catch (IOException ignore) {
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Wrapper around {@link BitmapFactory#decodeStream(InputStream, Rect,
+ * BitmapFactory.Options)} that returns {@code null} on {@link
+ * OutOfMemoryError}.
+ *
+ * @param is The input stream that holds the raw data to be decoded into a
+ * bitmap.
+ * @param outPadding If not null, return the padding rect for the bitmap if
+ * it exists, otherwise set padding to [-1,-1,-1,-1]. If
+ * no bitmap is returned (null) then padding is
+ * unchanged.
+ * @param opts null-ok; Options that control downsampling and whether the
+ * image should be completely decoded, or just is size returned.
+ * @return The decoded bitmap, or null if the image data could not be
+ * decoded, or, if opts is non-null, if opts requested only the
+ * size be returned (in opts.outWidth and opts.outHeight)
+ */
+ public static Bitmap decodeStream(InputStream is, Rect outPadding, BitmapFactory.Options opts) {
+ try {
+ return BitmapFactory.decodeStream(is, outPadding, opts);
+ } catch (OutOfMemoryError oome) {
+ Log.e(TAG, "ImageUtils#decodeStream(InputStream, Rect, Options) threw an OOME", oome);
+ return null;
+ }
+ }
+
+ /**
+ * Gets the image bounds
+ *
+ * @param resolver The ContentResolver
+ * @param uri The uri
+ *
+ * @return The image bounds
+ */
+ private static Point getImageBounds(ContentResolver resolver, Uri uri)
+ throws IOException {
+ final BitmapFactory.Options opts = new BitmapFactory.Options();
+ InputStream inputStream = null;
+ String scheme = uri.getScheme();
+ try {
+ opts.inJustDecodeBounds = true;
+ inputStream = openInputStream(resolver, uri);
+ decodeStream(inputStream, null, opts);
+
+ return new Point(opts.outWidth, opts.outHeight);
+ } finally {
+ try {
+ if (inputStream != null) {
+ inputStream.close();
+ }
+ } catch (IOException ignore) {
+ }
+ }
+ }
+
+ private static InputStream openInputStream(ContentResolver resolver, Uri uri) throws
+ FileNotFoundException {
+ String scheme = uri.getScheme();
+ if("http".equals(scheme) || "https".equals(scheme)) {
+ try {
+ return new URL(uri.toString()).openStream();
+ } catch (MalformedURLException e) {
+ // Fall-back to the previous behaviour, just in case
+ Log.w(TAG, "Could not convert the uri to url: " + uri.toString());
+ return resolver.openInputStream(uri);
+ } catch (IOException e) {
+ Log.w(TAG, "Could not open input stream for uri: " + uri.toString());
+ return null;
+ }
+ }
+ return resolver.openInputStream(uri);
+ }
+}