From 064d6000933354f7bf344a41e0caa7052401c903 Mon Sep 17 00:00:00 2001 From: ztenghui Date: Thu, 5 Sep 2013 15:47:58 -0700 Subject: Use contentObserver to refresh the data when dirty. Handle another setDataSource exception. Remove the old work around for refreshing after editing. bug:10390298 Change-Id: I8777364b96c86eeaf5581a96163aab823cd4b438 --- src/com/android/camera/CameraActivity.java | 59 ++++++++++++++-------- src/com/android/camera/data/LocalMediaData.java | 27 +++++----- .../android/camera/data/LocalMediaObserver.java | 47 +++++++++++++++++ 3 files changed, 100 insertions(+), 33 deletions(-) create mode 100644 src/com/android/camera/data/LocalMediaObserver.java (limited to 'src') diff --git a/src/com/android/camera/CameraActivity.java b/src/com/android/camera/CameraActivity.java index b8947e1b6..6f51154f9 100644 --- a/src/com/android/camera/CameraActivity.java +++ b/src/com/android/camera/CameraActivity.java @@ -68,6 +68,7 @@ import com.android.camera.data.FixedFirstDataAdapter; import com.android.camera.data.FixedLastDataAdapter; import com.android.camera.data.LocalData; import com.android.camera.data.LocalDataAdapter; +import com.android.camera.data.LocalMediaObserver; import com.android.camera.data.MediaDetails; import com.android.camera.data.SimpleViewData; import com.android.camera.tinyplanet.TinyPlanetFragment; @@ -116,10 +117,6 @@ public class CameraActivity extends Activity */ public static final int REQ_CODE_DONT_SWITCH_TO_PREVIEW = 142; - /** Request code for external image editor activities. */ - private static final int REQ_CODE_EDIT = 1; - - /** Whether onResume should reset the view to the preview. */ private boolean mResetToPreviewOnResume = true; @@ -174,6 +171,10 @@ public class CameraActivity extends Activity private Intent mStandardShareIntent; private ShareActionProvider mPanoramaShareActionProvider; private Intent mPanoramaShareIntent; + private LocalMediaObserver mLocalImagesObserver; + private LocalMediaObserver mLocalVideosObserver; + private boolean mActivityPaused; + private boolean mMediaDataChangedDuringPause; private final int DEFAULT_SYSTEM_UI_VISIBILITY = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION; @@ -913,6 +914,16 @@ public class CameraActivity extends Activity } setupNfcBeamPush(); + + mLocalImagesObserver = new LocalMediaObserver(mMainHandler, this); + mLocalVideosObserver = new LocalMediaObserver(mMainHandler, this); + + getContentResolver().registerContentObserver( + MediaStore.Images.Media.EXTERNAL_CONTENT_URI, true, + mLocalImagesObserver); + getContentResolver().registerContentObserver( + MediaStore.Video.Media.EXTERNAL_CONTENT_URI, true, + mLocalVideosObserver); } private void setRotationAnimation() { @@ -951,26 +962,12 @@ public class CameraActivity extends Activity mCurrentModule.onPauseBeforeSuper(); super.onPause(); mCurrentModule.onPauseAfterSuper(); + mActivityPaused = true; } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { - if (requestCode == REQ_CODE_EDIT && resultCode == RESULT_OK) { - Uri uri = data.getData(); - ContentResolver contentResolver = getContentResolver(); - if (uri == null) { - // If we don't have a particular uri returned, then we have - // to refresh all, it is not optimal, but works best so far. - // Also don't requestLoad() when in secure camera mode. - if (!mSecureCamera) { - mDataAdapter.requestLoad(contentResolver); - } - } else { - mDataAdapter.refresh(contentResolver, uri); - } - } - - if (requestCode == REQ_CODE_DONT_SWITCH_TO_PREVIEW | requestCode == REQ_CODE_EDIT) { + if (requestCode == REQ_CODE_DONT_SWITCH_TO_PREVIEW) { mResetToPreviewOnResume = false; } else { super.onActivityResult(requestCode, resultCode, data); @@ -1004,6 +1001,12 @@ public class CameraActivity extends Activity // starting an activity we want to return from to the filmstrip rather // than the preview. mResetToPreviewOnResume = true; + + mActivityPaused = false; + if (mMediaDataChangedDuringPause) { + mDataAdapter.requestLoad(getContentResolver()); + mMediaDataChangedDuringPause = false; + } } @Override @@ -1025,6 +1028,9 @@ public class CameraActivity extends Activity if (mSecureCamera) { unregisterReceiver(mScreenOffReceiver); } + getContentResolver().unregisterContentObserver(mLocalImagesObserver); + getContentResolver().unregisterContentObserver(mLocalVideosObserver); + super.onDestroy(); } @@ -1204,7 +1210,8 @@ public class CameraActivity extends Activity Intent intent = new Intent(Intent.ACTION_EDIT) .setDataAndType(data.getContentUri(), data.getMimeType()) .setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - startActivityForResult(Intent.createChooser(intent, null), REQ_CODE_EDIT); + startActivityForResult(Intent.createChooser(intent, null), + REQ_CODE_DONT_SWITCH_TO_PREVIEW); } /** @@ -1376,4 +1383,14 @@ public class CameraActivity extends Activity public CameraOpenErrorCallback getCameraOpenErrorCallback() { return mCameraOpenErrorCallback; } + + /** + * When the activity is paused and MediaObserver get onChange() call, then + * we would like to set a dirty bit to reload the data at onResume(). + */ + public void setDirtyWhenPaused() { + if (mActivityPaused && !mMediaDataChangedDuringPause) { + mMediaDataChangedDuringPause = true; + } + } } diff --git a/src/com/android/camera/data/LocalMediaData.java b/src/com/android/camera/data/LocalMediaData.java index 573da45db..17ddbca42 100644 --- a/src/com/android/camera/data/LocalMediaData.java +++ b/src/com/android/camera/data/LocalMediaData.java @@ -495,7 +495,7 @@ public abstract class LocalMediaData implements LocalData { return null; } Bitmap b = BitmapFactory.decodeFile(mPath, opts); - if (mOrientation != 0) { + if (mOrientation != 0 && b != null) { if (isCancelled() || !isUsing()) { return null; } @@ -742,18 +742,21 @@ public abstract class LocalMediaData implements LocalData { return null; } MediaMetadataRetriever retriever = new MediaMetadataRetriever(); - retriever.setDataSource(mPath); - byte[] data = retriever.getEmbeddedPicture(); Bitmap bitmap = null; - if (isCancelled() || !isUsing()) { - retriever.release(); - return null; - } - if (data != null) { - bitmap = BitmapFactory.decodeByteArray(data, 0, data.length); - } - if (bitmap == null) { - bitmap = retriever.getFrameAtTime(); + try { + retriever.setDataSource(mPath); + byte[] data = retriever.getEmbeddedPicture(); + if (!isCancelled() && isUsing()) { + if (data != null) { + bitmap = BitmapFactory.decodeByteArray(data, 0, data.length); + } + if (bitmap == null) { + bitmap = retriever.getFrameAtTime(); + } + } + } catch (IllegalArgumentException e) { + Log.e(TAG, "MediaMetadataRetriever.setDataSource() fail:" + + e.getMessage()); } retriever.release(); return bitmap; diff --git a/src/com/android/camera/data/LocalMediaObserver.java b/src/com/android/camera/data/LocalMediaObserver.java new file mode 100644 index 000000000..4dd0f8897 --- /dev/null +++ b/src/com/android/camera/data/LocalMediaObserver.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2013 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.camera.data; + +import android.database.ContentObserver; +import android.net.Uri; +import android.os.Handler; + +import com.android.camera.CameraActivity; + +/** + * Listening to the changes to the local image and video data. onChange will + * happen on the main thread. + */ +public class LocalMediaObserver extends ContentObserver { + + private final CameraActivity mActivity; + + public LocalMediaObserver(Handler handler, CameraActivity activity) { + super(handler); + mActivity = activity; + } + + @Override + public void onChange(boolean selfChange) { + this.onChange(selfChange, null); + } + + @Override + public void onChange(boolean selfChange, Uri uri) { + mActivity.setDirtyWhenPaused(); + } +} -- cgit v1.2.3