From 107009fa3120563f9bdcdcce9c1ba92e58761b7a Mon Sep 17 00:00:00 2001 From: Angus Kong Date: Mon, 8 Apr 2013 16:57:57 -0700 Subject: Refactor CameraDataAdapter for other data types. Change-Id: I4d925a4f2a9c2d6d14beda8781a1d4ca5cf3c1f4 --- src/com/android/camera/data/CameraDataAdapter.java | 388 ++++++++++++--------- 1 file changed, 215 insertions(+), 173 deletions(-) (limited to 'src/com/android/camera/data/CameraDataAdapter.java') diff --git a/src/com/android/camera/data/CameraDataAdapter.java b/src/com/android/camera/data/CameraDataAdapter.java index 7a75a6d3d..a55cc9d52 100644 --- a/src/com/android/camera/data/CameraDataAdapter.java +++ b/src/com/android/camera/data/CameraDataAdapter.java @@ -23,6 +23,7 @@ import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Matrix; import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; import android.os.AsyncTask; import android.provider.MediaStore; import android.provider.MediaStore.Images; @@ -48,37 +49,9 @@ public class CameraDataAdapter implements FilmStripView.DataAdapter { private static final String TAG = "CamreaFilmStripDataProvider"; private static final int DEFAULT_DECODE_SIZE = 3000; - private static final String ORDER_CLAUSE = ImageColumns.DATE_TAKEN + " DESC, " - + ImageColumns._ID + " DESC"; private static final String[] CAMERA_PATH = { Storage.DIRECTORY + "%" }; - private static final int COL_ID = 0; - private static final int COL_TITLE = 1; - private static final int COL_MIME_TYPE = 2; - private static final int COL_DATE_TAKEN = 3; - private static final int COL_DATE_MODIFIED = 4; - private static final int COL_DATA = 5; - private static final int COL_ORIENTATION = 6; - private static final int COL_WIDTH = 7; - private static final int COL_HEIGHT = 8; - private static final int COL_SIZE = 9; - - private static final String[] PROJECTION = { - ImageColumns._ID, // 0, int - ImageColumns.TITLE, // 1, string - ImageColumns.MIME_TYPE, // 2, tring - ImageColumns.DATE_TAKEN, // 3, int - ImageColumns.DATE_MODIFIED, // 4, int - ImageColumns.DATA, // 5, string - ImageColumns.ORIENTATION, // 6, int, 0, 90, 180, 270 - ImageColumns.WIDTH, // 7, int - ImageColumns.HEIGHT, // 8, int - ImageColumns.SIZE // 9, int - }; - - // 32K buffer. - private static final byte[] DECODE_TEMP_STORAGE = new byte[32 * 1024]; - - private List mImages; + + private List mImages; private Listener mListener; private View mCameraPreviewView; @@ -92,8 +65,8 @@ public class CameraDataAdapter implements FilmStripView.DataAdapter { mPlaceHolder = new ColorDrawable(placeHolderColor); } - public void setCameraPreviewInfo(int width, int height, int orientation) { - addOrReplaceCameraData(buildCameraImageData(width, height, orientation)); + public void setCameraPreviewInfo(int width, int height) { + addOrReplaceCameraData(buildCameraImageData(width, height)); } @Override @@ -117,7 +90,6 @@ public class CameraDataAdapter implements FilmStripView.DataAdapter { } } - @Override public void requestLoad(ContentResolver resolver) { QueryTask qtask = new QueryTask(); qtask.execute(resolver); @@ -129,17 +101,8 @@ public class CameraDataAdapter implements FilmStripView.DataAdapter { return null; } - LocalImageData data = mImages.get(dataID); - - if (data.isCameraData) return mCameraPreviewView; - - ImageView v = new ImageView(c); - v.setImageDrawable(mPlaceHolder); - - v.setScaleType(ImageView.ScaleType.FIT_XY); - LoadBitmapTask task = new LoadBitmapTask(data, v); - task.execute(); - return v; + return mImages.get(dataID).getView( + c, mSuggestedWidth, mSuggestedHeight, mPlaceHolder); } @Override @@ -147,88 +110,74 @@ public class CameraDataAdapter implements FilmStripView.DataAdapter { mListener = listener; } - private LocalImageData buildCameraImageData(int width, int height, int orientation) { - LocalImageData d = new LocalImageData(); - d.width = width; - d.height = height; - d.orientation = orientation; - d.isCameraData = true; - d.supportedAction = ImageData.ACTION_NONE; + private LocalData buildCameraImageData(int width, int height) { + LocalData d = new CameraPreviewData(width, height); return d; } - private void addOrReplaceCameraData(LocalImageData data) { - if (mImages == null) mImages = new ArrayList(); + private void addOrReplaceCameraData(LocalData data) { + if (mImages == null) mImages = new ArrayList(); if (mImages.size() == 0) { mImages.add(0, data); return; } - LocalImageData first = mImages.get(0); - if (first.isCameraData) { + LocalData first = mImages.get(0); + if (first.getType() == ImageData.TYPE_CAMERA_PREVIEW) { mImages.set(0, data); } else { mImages.add(0, data); } } - private LocalImageData buildCursorImageData(Cursor c) { - LocalImageData d = new LocalImageData(); - d.id = c.getInt(COL_ID); - d.title = c.getString(COL_TITLE); - d.mimeType = c.getString(COL_MIME_TYPE); - d.path = c.getString(COL_DATA); - d.orientation = c.getInt(COL_ORIENTATION); - d.width = c.getInt(COL_WIDTH); - d.height = c.getInt(COL_HEIGHT); - d.supportedAction = ImageData.ACTION_PROMOTE | ImageData.ACTION_DEMOTE; - if (d.width <= 0 || d.height <= 0) { - Log.v(TAG, "warning! zero dimension for " - + d.path + ":" + d.width + "x" + d.height); - Dimension dim = decodeDimension(d.path); - if (dim != null) { - d.width = dim.width; - d.height = dim.height; - } else { - Log.v(TAG, "warning! dimension decode failed for " + d.path); - Bitmap b = BitmapFactory.decodeFile(d.path); - if (b == null) return null; - d.width = b.getWidth(); - d.height = b.getHeight(); + private class QueryTask extends AsyncTask> { + @Override + protected List doInBackground(ContentResolver... resolver) { + List l = null; + Cursor c = resolver[0].query( + Images.Media.EXTERNAL_CONTENT_URI, + LocalPhotoData.QUERY_PROJECTION, + MediaStore.Images.Media.DATA + " like ? ", CAMERA_PATH, + LocalPhotoData.QUERY_ORDER); + if (c == null) return null; + + // build up the list. + l = new ArrayList(); + c.moveToFirst(); + while (!c.isLast()) { + LocalData data = LocalPhotoData.buildFromCursor(c); + if (data != null) { + l.add(data); + } else { + Log.e(TAG, "Error decoding file:" + + c.getString(LocalPhotoData.COL_DATA)); + } + c.moveToNext(); } + c.close(); + return l; } - if (d.orientation == 90 || d.orientation == 270) { - int b = d.width; - d.width = d.height; - d.height = b; - } - return d; - } - private Dimension decodeDimension(String path) { - BitmapFactory.Options opts = new BitmapFactory.Options(); - opts.inJustDecodeBounds = true; - Bitmap b = BitmapFactory.decodeFile(path, opts); - if (b == null) return null; - Dimension d = new Dimension(); - d.width = opts.outWidth; - d.height = opts.outHeight; - return d; - } - - private class Dimension { - public int width; - public int height; + @Override + protected void onPostExecute(List l) { + boolean changed = (l != mImages); + LocalData first = null; + if (mImages != null && mImages.size() > 0) { + first = mImages.get(0); + if (first.getType() != ImageData.TYPE_CAMERA_PREVIEW) first = null; + } + mImages = l; + if (first != null) addOrReplaceCameraData(first); + // both might be null. + if (changed) mListener.onDataLoaded(); + } } - private class LocalImageData implements FilmStripView.ImageData { - public boolean isCameraData; + private abstract static class LocalData implements FilmStripView.ImageData { public int id; public String title; public String mimeType; public String path; - // from MediaStore, can only be 0, 90, 180, 270; - public int orientation; // width and height should be adjusted according to orientation. public int width; public int height; @@ -245,101 +194,194 @@ public class CameraDataAdapter implements FilmStripView.DataAdapter { } @Override - public int getType() { - if (isCameraData) return ImageData.TYPE_CAMERA_PREVIEW; - return ImageData.TYPE_PHOTO; + public boolean isActionSupported(int action) { + return false; } @Override - public boolean isActionSupported(int action) { - return ((action & supportedAction) != 0); + abstract public int getType(); + + abstract View getView(Context c, int width, int height, Drawable placeHolder); + } + + private class CameraPreviewData extends LocalData { + private int mWidth; + private int mHeight; + + CameraPreviewData(int w, int h) { + mWidth = w; + mHeight = h; } @Override - public String toString() { - return "LocalImageData:" + ",data=" + path + ",mimeType=" + mimeType - + "," + width + "x" + height + ",orientation=" + orientation; + public int getWidth() { + return mWidth; } - } - private class QueryTask extends AsyncTask> { - private ContentResolver mResolver; - private LocalImageData mCameraImageData; + @Override + public int getHeight() { + return mHeight; + } @Override - protected List doInBackground(ContentResolver... resolver) { - List l = null; - Cursor c = resolver[0].query(Images.Media.EXTERNAL_CONTENT_URI, PROJECTION, - MediaStore.Images.Media.DATA + " like ? ", CAMERA_PATH, - ORDER_CLAUSE); - if (c == null) return null; - l = new ArrayList(); - c.moveToFirst(); - while (!c.isLast()) { - LocalImageData data = buildCursorImageData(c); - if (data != null) l.add(data); - else Log.e(TAG, "Error decoding file:" + c.getString(COL_DATA)); - c.moveToNext(); - } - c.close(); - return l; + public int getType() { + return ImageData.TYPE_CAMERA_PREVIEW; } @Override - protected void onPostExecute(List l) { - boolean changed = (l != mImages); - LocalImageData first = null; - if (mImages != null && mImages.size() > 0) { - first = mImages.get(0); - if (!first.isCameraData) first = null; - } - mImages = l; - if (first != null) addOrReplaceCameraData(first); - // both might be null. - if (changed && mListener != null) mListener.onDataLoaded(); + View getView(Context c, int width, int height, Drawable placeHolder) { + return mCameraPreviewView; } } - private class LoadBitmapTask extends AsyncTask { - private LocalImageData mData; - private ImageView mView; + private static class LocalPhotoData extends LocalData { + static final String QUERY_ORDER = ImageColumns.DATE_TAKEN + " DESC, " + + ImageColumns._ID + " DESC"; + static final String[] QUERY_PROJECTION = { + ImageColumns._ID, // 0, int + ImageColumns.TITLE, // 1, string + ImageColumns.MIME_TYPE, // 2, tring + ImageColumns.DATE_TAKEN, // 3, int + ImageColumns.DATE_MODIFIED, // 4, int + ImageColumns.DATA, // 5, string + ImageColumns.ORIENTATION, // 6, int, 0, 90, 180, 270 + ImageColumns.WIDTH, // 7, int + ImageColumns.HEIGHT, // 8, int + ImageColumns.SIZE // 9, int + }; + + private static final int COL_ID = 0; + private static final int COL_TITLE = 1; + private static final int COL_MIME_TYPE = 2; + private static final int COL_DATE_TAKEN = 3; + private static final int COL_DATE_MODIFIED = 4; + private static final int COL_DATA = 5; + private static final int COL_ORIENTATION = 6; + private static final int COL_WIDTH = 7; + private static final int COL_HEIGHT = 8; + private static final int COL_SIZE = 9; + + + // 32K buffer. + private static final byte[] DECODE_TEMP_STORAGE = new byte[32 * 1024]; + + // from MediaStore, can only be 0, 90, 180, 270; + public int orientation; + + static LocalPhotoData buildFromCursor(Cursor c) { + LocalPhotoData d = new LocalPhotoData(); + d.id = c.getInt(COL_ID); + d.title = c.getString(COL_TITLE); + d.mimeType = c.getString(COL_MIME_TYPE); + d.path = c.getString(COL_DATA); + d.orientation = c.getInt(COL_ORIENTATION); + d.width = c.getInt(COL_WIDTH); + d.height = c.getInt(COL_HEIGHT); + if (d.width <= 0 || d.height <= 0) { + Log.v(TAG, "warning! zero dimension for " + + d.path + ":" + d.width + "x" + d.height); + Dimension dim = decodeDimension(d.path); + if (dim != null) { + d.width = dim.width; + d.height = dim.height; + } else { + Log.v(TAG, "warning! dimension decode failed for " + d.path); + Bitmap b = BitmapFactory.decodeFile(d.path); + if (b == null) return null; + d.width = b.getWidth(); + d.height = b.getHeight(); + } + } + if (d.orientation == 90 || d.orientation == 270) { + int b = d.width; + d.width = d.height; + d.height = b; + } + return d; + } - public LoadBitmapTask( - LocalImageData d, ImageView v) { - mData = d; - mView = v; + @Override + View getView(Context c, + int decodeWidth, int decodeHeight, Drawable placeHolder) { + ImageView v = new ImageView(c); + v.setImageDrawable(placeHolder); + + v.setScaleType(ImageView.ScaleType.FIT_XY); + LoadBitmapTask task = new LoadBitmapTask(v, decodeWidth, decodeHeight); + task.execute(); + return v; + } + + + @Override + public String toString() { + return "LocalPhotoData:" + ",data=" + path + ",mimeType=" + mimeType + + "," + width + "x" + height + ",orientation=" + orientation; } @Override - protected Bitmap doInBackground(Void... v) { - BitmapFactory.Options opts = null; - Bitmap b; - int sample = 1; - while (mSuggestedWidth * sample < mData.width - || mSuggestedHeight * sample < mData.height) { - sample *= 2; + public int getType() { + return TYPE_PHOTO; + } + + private static Dimension decodeDimension(String path) { + BitmapFactory.Options opts = new BitmapFactory.Options(); + opts.inJustDecodeBounds = true; + Bitmap b = BitmapFactory.decodeFile(path, opts); + if (b == null) return null; + Dimension d = new Dimension(); + d.width = opts.outWidth; + d.height = opts.outHeight; + return d; + } + + private static class Dimension { + public int width; + public int height; + } + + private class LoadBitmapTask extends AsyncTask { + private ImageView mView; + private int mDecodeWidth; + private int mDecodeHeight; + + public LoadBitmapTask(ImageView v, int decodeWidth, int decodeHeight) { + mView = v; + mDecodeWidth = decodeWidth; + mDecodeHeight = decodeHeight; } - opts = new BitmapFactory.Options(); - opts.inSampleSize = sample; - opts.inTempStorage = DECODE_TEMP_STORAGE; - if (isCancelled()) return null; - b = BitmapFactory.decodeFile(mData.path, opts); - if (mData.orientation != 0) { + + @Override + protected Bitmap doInBackground(Void... v) { + BitmapFactory.Options opts = null; + Bitmap b; + int sample = 1; + while (mDecodeWidth * sample < width + || mDecodeHeight * sample < height) { + sample *= 2; + } + opts = new BitmapFactory.Options(); + opts.inSampleSize = sample; + opts.inTempStorage = DECODE_TEMP_STORAGE; if (isCancelled()) return null; - Matrix m = new Matrix(); - m.setRotate((float) mData.orientation); - b = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), m, false); + b = BitmapFactory.decodeFile(path, opts); + if (orientation != 0) { + if (isCancelled()) return null; + Matrix m = new Matrix(); + m.setRotate((float) orientation); + b = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), m, false); + } + return b; } - return b; - } - @Override - protected void onPostExecute(Bitmap bitmap) { - if (bitmap == null) { - Log.e(TAG, "Cannot decode bitmap file:" + mData.path); - return; + @Override + protected void onPostExecute(Bitmap bitmap) { + if (bitmap == null) { + Log.e(TAG, "Cannot decode bitmap file:" + path); + return; + } + mView.setImageBitmap(bitmap); } - mView.setImageBitmap(bitmap); } } } -- cgit v1.2.3