summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Guggemos <jimg@google.com>2012-12-04 12:48:27 -0700
committerJim Guggemos <jimg@google.com>2012-12-04 12:49:13 -0700
commit9c3046a1b1ee9d806562d280e4a0143d1cd428b0 (patch)
tree78f6bda8af730d282e5c89ee49f284ed214026a9
parent599730cf777402d183afa5b648ea1c8c1fab8118 (diff)
parentdccd6d91ca82225395af470595e4ffb8734dac1a (diff)
downloadphotoviewer-tools_r22.tar.gz
Change-Id: I4a338a8cf6650db88dfa1914dd4c0fa63c841d89
-rw-r--r--src/com/android/ex/photo/PhotoViewActivity.java90
-rw-r--r--src/com/android/ex/photo/PhotoViewCallbacks.java70
-rw-r--r--src/com/android/ex/photo/PhotoViewPager.java3
-rw-r--r--src/com/android/ex/photo/adapters/BaseCursorPagerAdapter.java14
-rw-r--r--src/com/android/ex/photo/adapters/BaseFragmentPagerAdapter.java9
-rw-r--r--src/com/android/ex/photo/adapters/PhotoPagerAdapter.java13
-rw-r--r--src/com/android/ex/photo/fragments/PhotoViewFragment.java84
-rw-r--r--src/com/android/ex/photo/loaders/PhotoBitmapLoader.java2
-rw-r--r--src/com/android/ex/photo/loaders/PhotoPagerLoader.java2
-rw-r--r--src/com/android/ex/photo/util/ImageUtils.java32
-rw-r--r--src/com/android/ex/photo/views/PhotoView.java4
11 files changed, 203 insertions, 120 deletions
diff --git a/src/com/android/ex/photo/PhotoViewActivity.java b/src/com/android/ex/photo/PhotoViewActivity.java
index 5e45f5e..5229375 100644
--- a/src/com/android/ex/photo/PhotoViewActivity.java
+++ b/src/com/android/ex/photo/PhotoViewActivity.java
@@ -21,15 +21,16 @@ import android.app.ActionBar;
import android.app.ActionBar.OnMenuVisibilityListener;
import android.app.Activity;
import android.app.ActivityManager;
-import android.app.Fragment;
-import android.app.LoaderManager.LoaderCallbacks;
import android.content.Intent;
-import android.content.Loader;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentActivity;
+import android.support.v4.app.LoaderManager;
+import android.support.v4.content.Loader;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.MenuItem;
import android.view.View;
@@ -47,53 +48,9 @@ import java.util.Set;
/**
* Activity to view the contents of an album.
*/
-public class PhotoViewActivity extends Activity implements
- LoaderCallbacks<Cursor>, OnPageChangeListener, OnInterceptTouchListener,
- OnMenuVisibilityListener {
-
- /**
- * Listener to be invoked for screen events.
- */
- public static interface OnScreenListener {
-
- /**
- * The full screen state has changed.
- */
- public void onFullScreenChanged(boolean fullScreen);
-
- /**
- * A new view has been activated and the previous view de-activated.
- */
- public void onViewActivated();
-
- /**
- * Called when a right-to-left touch move intercept is about to occur.
- *
- * @param origX the raw x coordinate of the initial touch
- * @param origY the raw y coordinate of the initial touch
- * @return {@code true} if the touch should be intercepted.
- */
- public boolean onInterceptMoveLeft(float origX, float origY);
-
- /**
- * Called when a left-to-right touch move intercept is about to occur.
- *
- * @param origX the raw x coordinate of the initial touch
- * @param origY the raw y coordinate of the initial touch
- * @return {@code true} if the touch should be intercepted.
- */
- public boolean onInterceptMoveRight(float origX, float origY);
- }
-
- public static interface CursorChangedListener {
- /**
- * Called when the cursor that contains the photo list data
- * is updated. Note that there is no guarantee that the cursor
- * will be at the proper position.
- * @param cursor the cursor containing the photo list data
- */
- public void onCursorChanged(Cursor cursor);
- }
+public class PhotoViewActivity extends FragmentActivity implements
+ LoaderManager.LoaderCallbacks<Cursor>, OnPageChangeListener, OnInterceptTouchListener,
+ OnMenuVisibilityListener, PhotoViewCallbacks {
private final static String STATE_ITEM_KEY =
"com.google.android.apps.plus.PhotoViewFragment.ITEM";
@@ -188,7 +145,7 @@ public class PhotoViewActivity extends Activity implements
setContentView(R.layout.photo_activity_view);
// Create the adapter and add the view pager
- mAdapter = new PhotoPagerAdapter(this, getFragmentManager(), null, mMaxInitialScale);
+ mAdapter = new PhotoPagerAdapter(this, getSupportFragmentManager(), null, mMaxInitialScale);
mViewPager = (PhotoViewPager) findViewById(R.id.photo_view_pager);
mViewPager.setAdapter(mAdapter);
@@ -196,7 +153,7 @@ public class PhotoViewActivity extends Activity implements
mViewPager.setOnInterceptTouchListener(this);
// Kick off the loader
- getLoaderManager().initLoader(LOADER_PHOTO_LIST, null, this);
+ getSupportLoaderManager().initLoader(LOADER_PHOTO_LIST, null, this);
final ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
@@ -214,7 +171,7 @@ public class PhotoViewActivity extends Activity implements
mIsPaused = false;
if (mRestartLoader) {
mRestartLoader = false;
- getLoaderManager().restartLoader(LOADER_PHOTO_LIST, null, this);
+ getSupportLoaderManager().restartLoader(LOADER_PHOTO_LIST, null, this);
}
}
@@ -253,22 +210,27 @@ public class PhotoViewActivity extends Activity implements
}
}
+ @Override
public void addScreenListener(OnScreenListener listener) {
mScreenListeners.add(listener);
}
+ @Override
public void removeScreenListener(OnScreenListener listener) {
mScreenListeners.remove(listener);
}
+ @Override
public synchronized void addCursorListener(CursorChangedListener listener) {
mCursorListeners.add(listener);
}
+ @Override
public synchronized void removeCursorListener(CursorChangedListener listener) {
mCursorListeners.remove(listener);
}
+ @Override
public boolean isFragmentFullScreen(Fragment fragment) {
if (mViewPager == null || mAdapter == null || mAdapter.getCount() == 0) {
return mFullScreen;
@@ -276,6 +238,7 @@ public class PhotoViewActivity extends Activity implements
return mFullScreen || (mViewPager.getCurrentItem() != mAdapter.getItemPosition(fragment));
}
+ @Override
public void toggleFullScreen() {
setFullScreen(!mFullScreen, true);
}
@@ -293,7 +256,7 @@ public class PhotoViewActivity extends Activity implements
return;
}
- getLoaderManager().restartLoader(LOADER_PHOTO_LIST, null, this);
+ getSupportLoaderManager().restartLoader(LOADER_PHOTO_LIST, null, this);
}
@Override
@@ -305,7 +268,7 @@ public class PhotoViewActivity extends Activity implements
}
@Override
- public void onLoadFinished(final Loader<Cursor> loader, final Cursor data) {
+ public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
final int id = loader.getId();
if (id == LOADER_PHOTO_LIST) {
if (data == null || data.getCount() == 0) {
@@ -342,6 +305,13 @@ public class PhotoViewActivity extends Activity implements
}
}
+ @Override
+ public void onLoaderReset(android.support.v4.content.Loader<Cursor> loader) {
+ // If the loader is reset, remove the reference in the adapter to this cursor
+ // TODO(pwestbro): reenable this when b/7075236 is fixed
+ // mAdapter.swapCursor(null);
+ }
+
protected void updateActionItems() {
// Do nothing, but allow extending classes to do work
}
@@ -355,13 +325,6 @@ public class PhotoViewActivity extends Activity implements
}
@Override
- public void onLoaderReset(Loader<Cursor> loader) {
- // If the loader is reset, remove the reference in the adapter to this cursor
- // TODO(pwestbro): reenable this when b/7075236 is fixed
- // mAdapter.swapCursor(null);
- }
-
- @Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@@ -375,6 +338,7 @@ public class PhotoViewActivity extends Activity implements
public void onPageScrollStateChanged(int state) {
}
+ @Override
public boolean isFragmentActive(Fragment fragment) {
if (mViewPager == null || mAdapter == null) {
return false;
@@ -478,6 +442,7 @@ public class PhotoViewActivity extends Activity implements
}
};
+ @Override
public void setViewActivated() {
for (OnScreenListener listener : mScreenListeners) {
listener.onViewActivated();
@@ -557,4 +522,5 @@ public class PhotoViewActivity extends Activity implements
protected void setPhotoIndex(int index) {
mPhotoIndex = index;
}
+
}
diff --git a/src/com/android/ex/photo/PhotoViewCallbacks.java b/src/com/android/ex/photo/PhotoViewCallbacks.java
new file mode 100644
index 0000000..2d4e84a
--- /dev/null
+++ b/src/com/android/ex/photo/PhotoViewCallbacks.java
@@ -0,0 +1,70 @@
+package com.android.ex.photo;
+
+import android.database.Cursor;
+import android.support.v4.app.Fragment;
+
+import com.android.ex.photo.fragments.PhotoViewFragment;
+
+public interface PhotoViewCallbacks {
+ /**
+ * Listener to be invoked for screen events.
+ */
+ public static interface OnScreenListener {
+
+ /**
+ * The full screen state has changed.
+ */
+ public void onFullScreenChanged(boolean fullScreen);
+
+ /**
+ * A new view has been activated and the previous view de-activated.
+ */
+ public void onViewActivated();
+
+ /**
+ * Called when a right-to-left touch move intercept is about to occur.
+ *
+ * @param origX the raw x coordinate of the initial touch
+ * @param origY the raw y coordinate of the initial touch
+ * @return {@code true} if the touch should be intercepted.
+ */
+ public boolean onInterceptMoveLeft(float origX, float origY);
+
+ /**
+ * Called when a left-to-right touch move intercept is about to occur.
+ *
+ * @param origX the raw x coordinate of the initial touch
+ * @param origY the raw y coordinate of the initial touch
+ * @return {@code true} if the touch should be intercepted.
+ */
+ public boolean onInterceptMoveRight(float origX, float origY);
+ }
+
+ public static interface CursorChangedListener {
+ /**
+ * Called when the cursor that contains the photo list data
+ * is updated. Note that there is no guarantee that the cursor
+ * will be at the proper position.
+ * @param cursor the cursor containing the photo list data
+ */
+ public void onCursorChanged(Cursor cursor);
+ }
+
+ public void addScreenListener(OnScreenListener listener);
+
+ public void removeScreenListener(OnScreenListener listener);
+
+ public void addCursorListener(CursorChangedListener listener);
+
+ public void removeCursorListener(CursorChangedListener listener);
+
+ public void setViewActivated();
+
+ public void toggleFullScreen();
+
+ public boolean isFragmentActive(Fragment fragment);
+
+ public void onFragmentVisible(PhotoViewFragment fragment);
+
+ public boolean isFragmentFullScreen(Fragment fragment);
+}
diff --git a/src/com/android/ex/photo/PhotoViewPager.java b/src/com/android/ex/photo/PhotoViewPager.java
index 65d1d6d..a18601c 100644
--- a/src/com/android/ex/photo/PhotoViewPager.java
+++ b/src/com/android/ex/photo/PhotoViewPager.java
@@ -39,7 +39,8 @@ public class PhotoViewPager extends ViewPager {
* <p>
* {@link ViewPager} intercepts all touch events and we need to be able to override this
* behavior. Instead, we could perform a similar function by declaring a custom
- * {@link ViewGroup} to contain the pager and intercept touch events at a higher level.
+ * {@link android.view.ViewGroup} to contain the pager and intercept touch events at a higher
+ * level.
*/
public static interface OnInterceptTouchListener {
/**
diff --git a/src/com/android/ex/photo/adapters/BaseCursorPagerAdapter.java b/src/com/android/ex/photo/adapters/BaseCursorPagerAdapter.java
index ae2c92e..9967662 100644
--- a/src/com/android/ex/photo/adapters/BaseCursorPagerAdapter.java
+++ b/src/com/android/ex/photo/adapters/BaseCursorPagerAdapter.java
@@ -17,10 +17,10 @@
package com.android.ex.photo.adapters;
-import android.app.Fragment;
-import android.app.FragmentManager;
import android.content.Context;
import android.database.Cursor;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentManager;
import android.util.Log;
import android.util.SparseIntArray;
import android.view.View;
@@ -37,13 +37,13 @@ import java.util.HashMap;
public abstract class BaseCursorPagerAdapter extends BaseFragmentPagerAdapter {
private static final String TAG = "BaseCursorPagerAdapter";
- Context mContext;
- private Cursor mCursor;
- private int mRowIDColumn;
+ protected Context mContext;
+ protected Cursor mCursor;
+ protected int mRowIDColumn;
/** Mapping of row ID to cursor position */
- private SparseIntArray mItemPosition;
+ protected SparseIntArray mItemPosition;
/** Mapping of instantiated object to row ID */
- private final HashMap<Object, Integer> mObjectRowMap = new HashMap<Object, Integer>();
+ protected final HashMap<Object, Integer> mObjectRowMap = new HashMap<Object, Integer>();
/**
* Constructor that always enables auto-requery.
diff --git a/src/com/android/ex/photo/adapters/BaseFragmentPagerAdapter.java b/src/com/android/ex/photo/adapters/BaseFragmentPagerAdapter.java
index 2065b2a..cfa06db 100644
--- a/src/com/android/ex/photo/adapters/BaseFragmentPagerAdapter.java
+++ b/src/com/android/ex/photo/adapters/BaseFragmentPagerAdapter.java
@@ -17,11 +17,10 @@
package com.android.ex.photo.adapters;
-import android.app.Fragment;
-import android.app.FragmentManager;
-import android.app.FragmentTransaction;
import android.os.Parcelable;
-import android.support.v4.app.FragmentPagerAdapter;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.PagerAdapter;
import android.util.Log;
import android.util.LruCache;
@@ -55,7 +54,7 @@ public abstract class BaseFragmentPagerAdapter extends PagerAdapter {
/** A cache to store detached fragments before they are removed */
private LruCache<String, Fragment> mFragmentCache = new FragmentCache(DEFAULT_CACHE_SIZE);
- public BaseFragmentPagerAdapter(FragmentManager fm) {
+ public BaseFragmentPagerAdapter(android.support.v4.app.FragmentManager fm) {
mFragmentManager = fm;
}
diff --git a/src/com/android/ex/photo/adapters/PhotoPagerAdapter.java b/src/com/android/ex/photo/adapters/PhotoPagerAdapter.java
index 4536432..121ef46 100644
--- a/src/com/android/ex/photo/adapters/PhotoPagerAdapter.java
+++ b/src/com/android/ex/photo/adapters/PhotoPagerAdapter.java
@@ -17,10 +17,9 @@
package com.android.ex.photo.adapters;
-import android.app.Fragment;
-import android.app.FragmentManager;
import android.content.Context;
import android.database.Cursor;
+import android.support.v4.app.Fragment;
import com.android.ex.photo.Intents;
import com.android.ex.photo.Intents.PhotoViewIntentBuilder;
@@ -31,12 +30,12 @@ import com.android.ex.photo.provider.PhotoContract;
* Pager adapter for the photo view
*/
public class PhotoPagerAdapter extends BaseCursorPagerAdapter {
- private int mContentUriIndex;
- private int mThumbnailUriIndex;
- private int mLoadingIndex;
- private final float mMaxScale;
+ protected int mContentUriIndex;
+ protected int mThumbnailUriIndex;
+ protected int mLoadingIndex;
+ protected final float mMaxScale;
- public PhotoPagerAdapter(Context context, FragmentManager fm, Cursor c, float maxScale) {
+ public PhotoPagerAdapter(Context context, android.support.v4.app.FragmentManager fm, Cursor c, float maxScale) {
super(context, fm, c);
mMaxScale = maxScale;
}
diff --git a/src/com/android/ex/photo/fragments/PhotoViewFragment.java b/src/com/android/ex/photo/fragments/PhotoViewFragment.java
index a721b26..abb47a0 100644
--- a/src/com/android/ex/photo/fragments/PhotoViewFragment.java
+++ b/src/com/android/ex/photo/fragments/PhotoViewFragment.java
@@ -18,15 +18,15 @@
package com.android.ex.photo.fragments;
import android.app.Activity;
-import android.app.Fragment;
-import android.app.LoaderManager;
-import android.app.LoaderManager.LoaderCallbacks;
import android.content.Context;
import android.content.Intent;
-import android.content.Loader;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.os.Bundle;
+import android.os.Handler;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.LoaderManager;
+import android.support.v4.content.Loader;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.View;
@@ -38,9 +38,9 @@ import android.widget.ProgressBar;
import android.widget.TextView;
import com.android.ex.photo.Intents;
-import com.android.ex.photo.PhotoViewActivity;
-import com.android.ex.photo.PhotoViewActivity.CursorChangedListener;
-import com.android.ex.photo.PhotoViewActivity.OnScreenListener;
+import com.android.ex.photo.PhotoViewCallbacks;
+import com.android.ex.photo.PhotoViewCallbacks.CursorChangedListener;
+import com.android.ex.photo.PhotoViewCallbacks.OnScreenListener;
import com.android.ex.photo.R;
import com.android.ex.photo.adapters.PhotoPagerAdapter;
import com.android.ex.photo.loaders.PhotoBitmapLoader;
@@ -52,7 +52,7 @@ import com.android.ex.photo.views.ProgressBarWrapper;
* Displays a photo.
*/
public class PhotoViewFragment extends Fragment implements
- LoaderCallbacks<Bitmap>, OnClickListener, OnScreenListener, CursorChangedListener {
+ LoaderManager.LoaderCallbacks<Bitmap>, OnClickListener, OnScreenListener, CursorChangedListener {
/**
* Interface for components that are internally scrollable left-to-right.
*/
@@ -77,42 +77,42 @@ public class PhotoViewFragment extends Fragment implements
public boolean interceptMoveRight(float origX, float origY);
}
- private final static String STATE_INTENT_KEY =
+ protected final static String STATE_INTENT_KEY =
"com.android.mail.photo.fragments.PhotoViewFragment.INTENT";
// Loader IDs
- private final static int LOADER_ID_PHOTO = 1;
- private final static int LOADER_ID_THUMBNAIL = 2;
+ protected final static int LOADER_ID_PHOTO = 1;
+ protected final static int LOADER_ID_THUMBNAIL = 2;
/** The size of the photo */
public static Integer sPhotoSize;
/** The URL of a photo to display */
- private String mResolvedPhotoUri;
- private String mThumbnailUri;
+ protected String mResolvedPhotoUri;
+ protected String mThumbnailUri;
/** The intent we were launched with */
- private Intent mIntent;
- private PhotoViewActivity mCallback;
- private PhotoPagerAdapter mAdapter;
+ protected Intent mIntent;
+ protected PhotoViewCallbacks mCallback;
+ protected PhotoPagerAdapter mAdapter;
- private PhotoView mPhotoView;
- private ImageView mPhotoPreviewImage;
- private TextView mEmptyText;
- private ImageView mRetryButton;
- private ProgressBarWrapper mPhotoProgressBar;
+ protected PhotoView mPhotoView;
+ protected ImageView mPhotoPreviewImage;
+ protected TextView mEmptyText;
+ protected ImageView mRetryButton;
+ protected ProgressBarWrapper mPhotoProgressBar;
- private final int mPosition;
+ protected final int mPosition;
/** Whether or not the fragment should make the photo full-screen */
- private boolean mFullScreen;
+ protected boolean mFullScreen;
/** Whether or not this fragment will only show the loading spinner */
- private final boolean mOnlyShowSpinner;
+ protected final boolean mOnlyShowSpinner;
/** Whether or not the progress bar is showing valid information about the progress stated */
- private boolean mProgressBarNeeded = true;
+ protected boolean mProgressBarNeeded = true;
- private View mPhotoPreviewAndProgress;
+ protected View mPhotoPreviewAndProgress;
public PhotoViewFragment() {
mPosition = -1;
@@ -132,7 +132,7 @@ public class PhotoViewFragment extends Fragment implements
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
- mCallback = (PhotoViewActivity) activity;
+ mCallback = (PhotoViewCallbacks) activity;
if (mCallback == null) {
throw new IllegalArgumentException(
"Activity must be a derived class of PhotoViewActivity");
@@ -193,7 +193,7 @@ public class PhotoViewFragment extends Fragment implements
mPhotoView.setMaxInitialScale(mIntent.getFloatExtra(Intents.EXTRA_MAX_INITIAL_SCALE, 1));
mPhotoView.setOnClickListener(this);
mPhotoView.setFullScreen(mFullScreen, false);
- mPhotoView.enableImageTransforms(true);
+ mPhotoView.enableImageTransforms(false);
mPhotoPreviewAndProgress = view.findViewById(R.id.photo_preview);
mPhotoPreviewImage = (ImageView) view.findViewById(R.id.photo_preview_image);
@@ -277,12 +277,20 @@ public class PhotoViewFragment extends Fragment implements
case LOADER_ID_PHOTO:
if (data != null) {
bindPhoto(data);
+ enableImageTransforms(true);
mPhotoPreviewAndProgress.setVisibility(View.GONE);
mProgressBarNeeded = false;
} else {
// Received a null result for the full size image. Instead attempt to load the
// thumbnail
- getLoaderManager().initLoader(LOADER_ID_THUMBNAIL, null, this);
+ Handler handler = new Handler();
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ getLoaderManager().initLoader(LOADER_ID_THUMBNAIL, null,
+ PhotoViewFragment.this);
+ }
+ });
}
break;
case LOADER_ID_THUMBNAIL:
@@ -298,7 +306,15 @@ public class PhotoViewFragment extends Fragment implements
mPhotoPreviewImage.setImageResource(R.drawable.default_image);
} else {
bindPhoto(data);
- getLoaderManager().initLoader(LOADER_ID_PHOTO, null, this);
+ enableImageTransforms(false);
+ Handler handler = new Handler();
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ getLoaderManager().initLoader(LOADER_ID_PHOTO, null,
+ PhotoViewFragment.this);
+ }
+ });
}
break;
default:
@@ -324,6 +340,14 @@ public class PhotoViewFragment extends Fragment implements
}
/**
+ * Enable or disable image transformations. When transformations are enabled, this view
+ * consumes all touch events.
+ */
+ public void enableImageTransforms(boolean enable) {
+ mPhotoView.enableImageTransforms(enable);
+ }
+
+ /**
* Resets the photo view to it's default state w/ no bound photo.
*/
private void resetPhotoView() {
diff --git a/src/com/android/ex/photo/loaders/PhotoBitmapLoader.java b/src/com/android/ex/photo/loaders/PhotoBitmapLoader.java
index fe42e0d..d4d8b60 100644
--- a/src/com/android/ex/photo/loaders/PhotoBitmapLoader.java
+++ b/src/com/android/ex/photo/loaders/PhotoBitmapLoader.java
@@ -17,11 +17,11 @@
package com.android.ex.photo.loaders;
-import android.content.AsyncTaskLoader;
import android.content.ContentResolver;
import android.content.Context;
import android.graphics.Bitmap;
import android.net.Uri;
+import android.support.v4.content.AsyncTaskLoader;
import android.util.DisplayMetrics;
import com.android.ex.photo.fragments.PhotoViewFragment;
diff --git a/src/com/android/ex/photo/loaders/PhotoPagerLoader.java b/src/com/android/ex/photo/loaders/PhotoPagerLoader.java
index 7ba932b..72a6be1 100644
--- a/src/com/android/ex/photo/loaders/PhotoPagerLoader.java
+++ b/src/com/android/ex/photo/loaders/PhotoPagerLoader.java
@@ -18,9 +18,9 @@
package com.android.ex.photo.loaders;
import android.content.Context;
-import android.content.CursorLoader;
import android.database.Cursor;
import android.net.Uri;
+import android.support.v4.content.CursorLoader;
import com.android.ex.photo.provider.PhotoContract;
diff --git a/src/com/android/ex/photo/util/ImageUtils.java b/src/com/android/ex/photo/util/ImageUtils.java
index f37a1ad..250c870 100644
--- a/src/com/android/ex/photo/util/ImageUtils.java
+++ b/src/com/android/ex/photo/util/ImageUtils.java
@@ -25,7 +25,7 @@ import android.graphics.Point;
import android.graphics.Rect;
import android.net.Uri;
import android.os.Build;
-import android.util.DisplayMetrics;
+import android.util.Base64;
import android.util.Log;
import com.android.ex.photo.PhotoViewActivity;
@@ -38,6 +38,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
+import java.util.regex.Pattern;
/**
@@ -52,6 +53,9 @@ public class ImageUtils {
/** Minimum class memory class to use small photos */
private final static long MIN_SMALL_CLASS = 24;
+ private static final String BASE64_URI_PREFIX = "base64,";
+ private static final Pattern BASE64_IMAGE_URI_PATTERN = Pattern.compile("^(?:.*;)?base64,.*");
+
public static enum ImageSize {
EXTRA_SMALL,
SMALL,
@@ -234,7 +238,7 @@ public class ImageUtils {
private static InputStream openInputStream(ContentResolver resolver, Uri uri) throws
FileNotFoundException {
String scheme = uri.getScheme();
- if("http".equals(scheme) || "https".equals(scheme)) {
+ if ("http".equals(scheme) || "https".equals(scheme)) {
try {
return new URL(uri.toString()).openStream();
} catch (MalformedURLException e) {
@@ -245,7 +249,31 @@ public class ImageUtils {
Log.w(TAG, "Could not open input stream for uri: " + uri.toString());
return null;
}
+ } else if ("data".equals(scheme)) {
+ byte[] data = parseDataUri(uri);
+ if (data != null) {
+ return new ByteArrayInputStream(data);
+ }
}
return resolver.openInputStream(uri);
}
+
+ private static byte[] parseDataUri(Uri uri) {
+ String ssp = uri.getSchemeSpecificPart();
+ try {
+ if (ssp.startsWith(BASE64_URI_PREFIX)) {
+ String base64 = ssp.substring(BASE64_URI_PREFIX.length());
+ return Base64.decode(base64, Base64.URL_SAFE);
+ } else if (BASE64_IMAGE_URI_PATTERN.matcher(ssp).matches()){
+ String base64 = ssp.substring(
+ ssp.indexOf(BASE64_URI_PREFIX) + BASE64_URI_PREFIX.length());
+ return Base64.decode(base64, Base64.DEFAULT);
+ } else {
+ return null;
+ }
+ } catch (IllegalArgumentException ex) {
+ Log.e(TAG, "Mailformed data URI: " + ex);
+ return null;
+ }
+ }
}
diff --git a/src/com/android/ex/photo/views/PhotoView.java b/src/com/android/ex/photo/views/PhotoView.java
index 838a60d..0bc704e 100644
--- a/src/com/android/ex/photo/views/PhotoView.java
+++ b/src/com/android/ex/photo/views/PhotoView.java
@@ -18,7 +18,6 @@
package com.android.ex.photo.views;
import android.content.Context;
-import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
@@ -73,9 +72,6 @@ public class PhotoView extends View implements OnGestureListener,
/** Video icon */
private static Bitmap sVideoNotReadyImage;
- // Features
- private static boolean sHasMultitouchDistinct;
-
// Paints
/** Paint to partially dim the photo during crop */
private static Paint sCropDimPaint;