summaryrefslogtreecommitdiffstats
path: root/src/com/android/camera/Camera.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/camera/Camera.java')
-rw-r--r--src/com/android/camera/Camera.java418
1 files changed, 272 insertions, 146 deletions
diff --git a/src/com/android/camera/Camera.java b/src/com/android/camera/Camera.java
index 8b4de05..a0149df 100644
--- a/src/com/android/camera/Camera.java
+++ b/src/com/android/camera/Camera.java
@@ -16,6 +16,16 @@
package com.android.camera;
+import com.android.camera.gallery.IImage;
+import com.android.camera.gallery.IImageList;
+import com.android.camera.ui.BasicSettingPicker;
+import com.android.camera.ui.CameraHeadUpDisplay;
+import com.android.camera.ui.GLRootView;
+import com.android.camera.ui.HeadUpDisplay;
+import com.android.camera.ui.ControlPanel;
+import com.android.camera.ui.ZoomControllerListener;
+import com.android.camera.ui.ZoomPicker;
+
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
@@ -24,10 +34,10 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.res.Configuration;
import android.content.res.Resources;
+import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.hardware.Camera.CameraInfo;
@@ -43,18 +53,17 @@ import android.media.ToneGenerator;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
-import android.os.Debug;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.MessageQueue;
-import android.os.SystemClock;
import android.provider.MediaStore;
import android.provider.Settings;
+import android.provider.MediaStore.Images.ImageColumns;
+import android.provider.MediaStore.Images.Media;
import android.util.AttributeSet;
import android.util.Log;
-import android.view.Display;
import android.view.GestureDetector;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@@ -66,18 +75,16 @@ import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
+import android.view.ViewStub;
import android.view.Window;
import android.view.WindowManager;
import android.view.MenuItem.OnMenuItemClickListener;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.Button;
+import android.widget.CursorAdapter;
import android.widget.FrameLayout;
-import android.widget.ImageView;
-
-import com.android.camera.gallery.IImage;
-import com.android.camera.gallery.IImageList;
-import com.android.camera.ui.CameraHeadUpDisplay;
-import com.android.camera.ui.GLRootView;
-import com.android.camera.ui.HeadUpDisplay;
-import com.android.camera.ui.ZoomControllerListener;
+import android.widget.ListView;
import java.io.File;
import java.io.FileNotFoundException;
@@ -130,6 +137,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
private int mZoomValue; // The current zoom value.
private int mZoomMax;
private int mTargetZoomValue;
+ private ZoomPicker mZoomPicker;
private Parameters mParameters;
private Parameters mInitialParams;
@@ -163,10 +171,15 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
private GLRootView mGLRootView;
- // mPostCaptureAlert, mLastPictureButton, mThumbController
- // are non-null only if isImageCaptureIntent() is true.
- private ImageView mLastPictureButton;
- private ThumbnailController mThumbController;
+ // The layouts of small devices have a thumbnail button, which shows the last
+ // captured picture.
+ private RotateImageView mThumbnailButton;
+ // The layouts of xlarge devices have a list of thumbnails, which show the
+ // last captured pictures.
+ private ListView mThumbnailList;
+ private OnItemClickListener mThumbnailItemClickListener =
+ new ThumbnailItemClickListener();
+ private ThumbnailAdapter mThumbnailAdapter;
// mCropValue and mSaveUri are used only if isImageCaptureIntent() is true.
private String mCropValue;
@@ -174,6 +187,15 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
private ImageCapture mImageCapture = null;
+ /**
+ * An unpublished intent flag requesting to return as soon as capturing
+ * is completed.
+ *
+ * TODO: consider publishing by moving into MediaStore.
+ */
+ private final static String EXTRA_QUICK_CAPTURE =
+ "android.intent.extra.quickCapture";
+
private boolean mPreviewing;
private boolean mPausing;
private boolean mFirstTimeInitialized;
@@ -230,12 +252,18 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
private String mSceneMode;
private final Handler mHandler = new MainHandler();
+ // Small devices use head-up display for camera settings.
private CameraHeadUpDisplay mHeadUpDisplay;
+ // xlarge devices use control panel for camera settings.
+ private ControlPanel mControlPanel;
+ private PreferenceGroup mPreferenceGroup;
// multiple cameras support
private int mNumberOfCameras;
private int mCameraId;
+ private boolean mQuickCapture;
+
/**
* This Handler is used to post message back onto the main thread of the
* application
@@ -323,14 +351,8 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
mContentResolver = getContentResolver();
if (!mIsImageCaptureIntent) {
findViewById(R.id.camera_switch).setOnClickListener(this);
- mLastPictureButton =
- (ImageView) findViewById(R.id.review_thumbnail);
- mLastPictureButton.setOnClickListener(this);
- mThumbController = new ThumbnailController(
- getResources(), mLastPictureButton, mContentResolver);
- mThumbController.loadData(ImageManager.getLastImageThumbPath());
- // Update last image thumbnail.
- updateThumbnailButton();
+ initThumbnailButton();
+ initThumbnailList();
}
// Initialize shutter button.
@@ -345,8 +367,10 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
installIntentFilter();
initializeFocusTone();
initializeZoom();
- mHeadUpDisplay = new CameraHeadUpDisplay(this);
- mHeadUpDisplay.setListener(new MyHeadUpDisplayListener());
+ if (mControlPanel == null) {
+ mHeadUpDisplay = new CameraHeadUpDisplay(this);
+ mHeadUpDisplay.setListener(new MyHeadUpDisplayListener());
+ }
initializeHeadUpDisplay();
mFirstTimeInitialized = true;
changeHeadUpDisplayState();
@@ -363,12 +387,95 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
});
}
+ private void initThumbnailButton() {
+ mThumbnailButton =
+ (RotateImageView) findViewById(R.id.review_thumbnail);
+ if (mThumbnailButton != null) {
+ mThumbnailButton.setOnClickListener(this);
+ mThumbnailButton.loadData(ImageManager.getLastImageThumbPath());
+ updateThumbnailButton();
+ }
+ }
+
private void updateThumbnailButton() {
+ if (mThumbnailButton == null) return;
// Update last image if URI is invalid and the storage is ready.
- if (!mThumbController.isUriValid() && mPicturesRemaining >= 0) {
- updateLastImage();
+ if (!mThumbnailButton.isUriValid() && mPicturesRemaining >= 0) {
+ IImageList list = ImageManager.makeImageList(
+ mContentResolver,
+ dataLocation(),
+ ImageManager.INCLUDE_IMAGES,
+ ImageManager.SORT_ASCENDING,
+ ImageManager.CAMERA_IMAGE_BUCKET_ID);
+ int count = list.getCount();
+ if (count > 0) {
+ IImage image = list.getImageAt(count - 1);
+ Uri uri = image.fullSizeImageUri();
+ mThumbnailButton.setData(uri, image.miniThumbBitmap());
+ } else {
+ mThumbnailButton.setData(null, null);
+ }
+ list.close();
}
- mThumbController.updateDisplayIfNeeded();
+ }
+
+ private void setLastPictureThumb(byte[] data, int degree, Uri uri) {
+ if (mThumbnailButton == null) return;
+ BitmapFactory.Options options = new BitmapFactory.Options();
+ options.inSampleSize = 16;
+ Bitmap lastPictureThumb =
+ BitmapFactory.decodeByteArray(data, 0, data.length, options);
+ lastPictureThumb = Util.rotate(lastPictureThumb, degree);
+ mThumbnailButton.setData(uri, lastPictureThumb);
+ }
+
+ private void initThumbnailList() {
+ mThumbnailList = (ListView) findViewById(R.id.thumbnail_list);
+ if (mThumbnailList == null) return;
+
+ int width = mThumbnailList.getWidth();
+ int height = mThumbnailList.getHeight();
+
+ // Add gallery button to header view.
+ if (mThumbnailList.getHeaderViewsCount() == 0) {
+ LayoutInflater inflater = getLayoutInflater();
+ Button b = new Button(this);
+ ListView.LayoutParams params = new ListView.LayoutParams(width, width);
+ b.setId(R.id.btn_gallery);
+ b.setLayoutParams(params);
+ b.setOnClickListener(this);
+ b.setBackgroundResource(R.drawable.ic_menu_gallery);
+ mThumbnailList.addHeaderView(b);
+ }
+
+ // Set data adapter.
+ int thumbnailCount = (height + mThumbnailList.getDividerHeight())
+ / (width + mThumbnailList.getDividerHeight()) - 1;
+ Cursor cursor = getThumbnailsCursor(thumbnailCount);
+ mThumbnailAdapter = new ThumbnailAdapter(
+ getApplicationContext(), R.layout.thumbnail_item, cursor, true);
+ mThumbnailList.setAdapter(mThumbnailAdapter);
+ mThumbnailList.setOnItemClickListener(mThumbnailItemClickListener);
+ }
+
+ private void updateThumbnailList() {
+ if (mThumbnailList == null) return;
+ mThumbnailAdapter.getCursor().requery();
+ mThumbnailAdapter.notifyDataSetChanged();
+ }
+
+ private Cursor getThumbnailsCursor(int thumbnailCount) {
+ Log.v(TAG, "thumbnailCount=" + thumbnailCount);
+ String[] projections = { MediaStore.Images.Thumbnails._ID };
+ Uri uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
+ .buildUpon()
+ .appendQueryParameter("limit", String.valueOf(thumbnailCount))
+ .build();
+ // TODO: managedQuery is deprecated.
+ return managedQuery(uri, projections,
+ Media.MIME_TYPE + " = 'image/jpeg' AND " + Media.BUCKET_ID + " = ?",
+ new String[] {ImageManager.CAMERA_IMAGE_BUCKET_ID},
+ ImageColumns._ID + " DESC");
}
// If the activity is paused and resumed, this method will be called in
@@ -402,6 +509,15 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
mZoomMax = mParameters.getMaxZoom();
mSmoothZoomSupported = mParameters.isSmoothZoomSupported();
mGestureDetector = new GestureDetector(this, new ZoomGestureListener());
+ if (mZoomPicker != null) {
+ mZoomPicker.setZoomRatios(getZoomRatios());
+ mZoomPicker.setOnZoomChangeListener(
+ new ZoomPicker.OnZoomChangedListener() {
+ public void onZoomChanged(int index) {
+ onZoomValueChanged(index);
+ }
+ });
+ }
mCameraDevice.setZoomChangeListener(mZoomListener);
}
@@ -447,6 +563,13 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
return false;
}
+ int x = Math.round(e.getX());
+ int y = Math.round(e.getY());
+ if (x < mSurfaceView.getLeft() || x > mSurfaceView.getRight()
+ || y < mSurfaceView.getTop() || y > mSurfaceView.getBottom()) {
+ return false;
+ }
+
if (mZoomValue < mZoomMax) {
// Zoom in to the maximum.
mZoomValue = mZoomMax;
@@ -456,7 +579,11 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
setCameraParametersWhenIdle(UPDATE_PARAM_ZOOM);
- mHeadUpDisplay.setZoomIndex(mZoomValue);
+ if (mZoomPicker != null) {
+ mZoomPicker.setZoomIndex(mZoomValue);
+ } else {
+ mHeadUpDisplay.setZoomIndex(mZoomValue);
+ }
return true;
}
}
@@ -486,6 +613,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
checkStorage();
if (!mIsImageCaptureIntent) {
updateThumbnailButton();
+ updateThumbnailList();
}
}
}
@@ -608,7 +736,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
}
Log.v(TAG, "mPictureDisplayedToJpegCallbackTime = "
+ mPictureDisplayedToJpegCallbackTime + "ms");
- mHeadUpDisplay.setEnabled(true);
+ enableCameraControls(true);
if (!mIsImageCaptureIntent) {
// We want to show the taken picture for a while, so we wait
@@ -747,10 +875,14 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
"com.android.camera.NEW_PICTURE", mLastContentUri));
setLastPictureThumb(data, degree,
mImageCapture.getLastCaptureUri());
- mThumbController.updateDisplayIfNeeded();
+ updateThumbnailList();
} else {
mCaptureOnlyData = data;
- showPostCaptureAlert();
+ if (!mQuickCapture) {
+ showPostCaptureAlert();
+ } else {
+ doAttach();
+ }
}
}
@@ -839,7 +971,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
}
mCaptureStartTime = System.currentTimeMillis();
mPostViewPictureCallbackTime = 0;
- mHeadUpDisplay.setEnabled(false);
+ enableCameraControls(false);
mStatus = SNAPSHOT_IN_PROGRESS;
mImageCapture.initiate();
@@ -863,15 +995,6 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
return true;
}
- private void setLastPictureThumb(byte[] data, int degree, Uri uri) {
- BitmapFactory.Options options = new BitmapFactory.Options();
- options.inSampleSize = 16;
- Bitmap lastPictureThumb =
- BitmapFactory.decodeByteArray(data, 0, data.length, options);
- lastPictureThumb = Util.rotate(lastPictureThumb, degree);
- mThumbController.setData(uri, lastPictureThumb);
- }
-
private String createName(long dateTaken) {
Date date = new Date(dateTaken);
SimpleDateFormat dateFormat = new SimpleDateFormat(
@@ -894,6 +1017,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
CameraSettings.upgradeLocalPreferences(mPreferences.getLocal());
mNumberOfCameras = CameraHolder.instance().getNumberOfCameras();
+ mQuickCapture = getIntent().getBooleanExtra(EXTRA_QUICK_CAPTURE, false);
// we need to reset exposure for the preview
resetExposureCompensation();
@@ -946,6 +1070,10 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
mSwitcher.addTouchView(findViewById(R.id.camera_switch_set));
}
+ // Show zoom picker.
+ ViewStub zoomStub = (ViewStub) findViewById(R.id.zoom_stub);
+ if (zoomStub != null) mZoomPicker = (ZoomPicker) zoomStub.inflate();
+
// Make sure preview is started.
try {
startPreviewThread.join();
@@ -956,9 +1084,12 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
} catch (InterruptedException ex) {
// ignore
}
+
+ initializeControlPanel();
}
private void changeHeadUpDisplayState() {
+ if (mHeadUpDisplay == null) return;
// If the camera resumes behind the lock screen, the orientation
// will be portrait. That causes OOM when we try to allocation GPU
// memory for the GLSurfaceView again when the orientation changes. So,
@@ -992,13 +1123,32 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
}
}
+ private void initializeControlPanel() {
+ String[] keys = new String[]{CameraSettings.KEY_FLASH_MODE,
+ CameraSettings.KEY_WHITE_BALANCE,
+ CameraSettings.KEY_COLOR_EFFECT,
+ CameraSettings.KEY_CAMERA_ID};
+ mControlPanel = (ControlPanel) findViewById(R.id.control_panel);
+ if (mControlPanel != null) {
+ CameraSettings settings = new CameraSettings(this, mInitialParams,
+ mCameraId, CameraHolder.instance().getCameraInfo());
+ mPreferenceGroup = settings.getPreferenceGroup(R.xml.camera_preferences);
+ mControlPanel.initialize(this, mPreferenceGroup, keys, true);
+ mControlPanel.setListener(new MyControlPanelListener());
+ }
+ }
+
private void initializeHeadUpDisplay() {
+ if (mHeadUpDisplay == null) return;
CameraSettings settings = new CameraSettings(this, mInitialParams,
- CameraHolder.instance().getCameraInfo());
+ mCameraId, CameraHolder.instance().getCameraInfo());
+ // If we have zoom picker, do not show zoom control on head-up display.
+ float[] zoomRatios = null;
+ if (mZoomPicker == null) zoomRatios = getZoomRatios();
mHeadUpDisplay.initialize(this,
settings.getPreferenceGroup(R.xml.camera_preferences),
- getZoomRatios(), mOrientationCompensation);
- if (mParameters.isZoomSupported()) {
+ zoomRatios, mOrientationCompensation);
+ if (mZoomPicker == null && mParameters.isZoomSupported()) {
mHeadUpDisplay.setZoomListener(new ZoomControllerListener() {
public void onZoomChanged(
int index, float ratio, boolean isMoving) {
@@ -1027,6 +1177,21 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
mGLRootView = null;
}
+ private boolean collapseCameraControls() {
+ if (mHeadUpDisplay != null && mHeadUpDisplay.collapse()) {
+ return true;
+ }
+ if (mControlPanel != null && mControlPanel.hideSettingPicker()) {
+ return true;
+ }
+ return false;
+ }
+
+ private void enableCameraControls(boolean enable) {
+ if (mHeadUpDisplay != null) mHeadUpDisplay.setEnabled(enable);
+ if (mControlPanel != null) mControlPanel.setEnabled(enable);
+ }
+
public static int roundOrientation(int orientation) {
return ((orientation + 45) / 90 * 90) % 360;
}
@@ -1043,24 +1208,27 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
// the camera then point the camera to floor or sky, we still have
// the correct orientation.
if (orientation == ORIENTATION_UNKNOWN) return;
- mOrientation = roundOrientation(orientation);
- // When the screen is unlocked, display rotation may change. Always
- // calculate the up-to-date orientationCompensation.
- int orientationCompensation = mOrientation
- + Util.getDisplayRotation(Camera.this);
- if (mOrientationCompensation != orientationCompensation) {
- mOrientationCompensation = orientationCompensation;
+ orientation = roundOrientation(orientation);
+ if (orientation != mOrientation) {
+ mOrientation = orientation;
+ mOrientationCompensation = orientation
+ + Util.getDisplayRotation(Camera.this);
+
if (!mIsImageCaptureIntent) {
setOrientationIndicator(mOrientationCompensation);
}
- mHeadUpDisplay.setOrientation(mOrientationCompensation);
+ if (mHeadUpDisplay != null) {
+ mHeadUpDisplay.setOrientation(mOrientationCompensation);
+ }
}
}
}
private void setOrientationIndicator(int degree) {
- ((RotateImageView) findViewById(
- R.id.review_thumbnail)).setDegree(degree);
+ RotateImageView thumbnail = (RotateImageView) findViewById(
+ R.id.review_thumbnail);
+ if (thumbnail != null) thumbnail.setDegree(degree);
+
((RotateImageView) findViewById(
R.id.camera_switch_icon)).setDegree(degree);
((RotateImageView) findViewById(
@@ -1097,7 +1265,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
break;
case R.id.review_thumbnail:
if (isCameraIdle()) {
- viewLastImage();
+ viewImage(mThumbnailButton);
}
break;
case R.id.btn_done:
@@ -1105,9 +1273,19 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
break;
case R.id.btn_cancel:
doCancel();
+ break;
+ case R.id.btn_gallery:
+ gotoGallery();
+ break;
}
}
+ private class ThumbnailItemClickListener implements OnItemClickListener {
+ public void onItemClick(AdapterView<?> p, View v, int pos, long id) {
+ viewImage((RotateImageView)v);
+ }
+ }
+
private Bitmap createCaptureBitmap(byte[] data) {
// This is really stupid...we just want to read the orientation in
// the jpeg header.
@@ -1337,13 +1515,16 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
// Close the camera now because other activities may need to use it.
closeCamera();
resetScreenOn();
+ collapseCameraControls();
changeHeadUpDisplayState();
if (mFirstTimeInitialized) {
mOrientationListener.disable();
if (!mIsImageCaptureIntent) {
- mThumbController.storeData(
- ImageManager.getLastImageThumbPath());
+ if (mThumbnailButton != null) {
+ mThumbnailButton.storeData(
+ ImageManager.getLastImageThumbPath());
+ }
}
hidePostCaptureAlert();
}
@@ -1407,7 +1588,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
// Initiate autofocus only when preview is started and snapshot is not
// in progress.
if (canTakePicture()) {
- mHeadUpDisplay.setEnabled(false);
+ enableCameraControls(false);
Log.v(TAG, "Start autofocus.");
mFocusStartTime = System.currentTimeMillis();
mFocusState = FOCUSING;
@@ -1421,7 +1602,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
if (mStatus != SNAPSHOT_IN_PROGRESS && (mFocusState == FOCUSING
|| mFocusState == FOCUS_SUCCESS || mFocusState == FOCUS_FAIL)) {
Log.v(TAG, "Cancel autofocus.");
- mHeadUpDisplay.setEnabled(true);
+ enableCameraControls(true);
mCameraDevice.cancelAutoFocus();
}
if (mFocusState != FOCUSING_SNAP_ON_FINISH) {
@@ -1453,7 +1634,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
if (!isCameraIdle()) {
// ignore backs while we're taking a picture
return;
- } else if (mHeadUpDisplay == null || !mHeadUpDisplay.collapse()) {
+ } else if (!collapseCameraControls()) {
super.onBackPressed();
}
}
@@ -1478,7 +1659,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
// Start auto-focus immediately to reduce shutter lag. After
// the shutter button gets the focus, doFocus() will be
// called again but it is fine.
- if (mHeadUpDisplay.collapse()) return true;
+ if (collapseCameraControls()) return true;
doFocus(true);
if (mShutterButton.isInTouchMode()) {
mShutterButton.requestFocusFromTouch();
@@ -1506,7 +1687,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
}
private void doSnap() {
- if (mHeadUpDisplay.collapse()) return;
+ if (collapseCameraControls()) return;
Log.v(TAG, "doSnap: mFocusState=" + mFocusState);
// If the user has half-pressed the shutter and focus is completed, we
@@ -1530,7 +1711,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
private void doFocus(boolean pressed) {
// Do the focus if the mode is not infinity.
- if (mHeadUpDisplay.collapse()) return;
+ if (collapseCameraControls()) return;
if (!(mFocusMode.equals(Parameters.FOCUS_MODE_INFINITY)
|| mFocusMode.equals(Parameters.FOCUS_MODE_FIXED)
|| mFocusMode.equals(Parameters.FOCUS_MODE_EDOF))) {
@@ -1610,24 +1791,6 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
}
}
- private void updateLastImage() {
- IImageList list = ImageManager.makeImageList(
- mContentResolver,
- dataLocation(),
- ImageManager.INCLUDE_IMAGES,
- ImageManager.SORT_ASCENDING,
- ImageManager.CAMERA_IMAGE_BUCKET_ID);
- int count = list.getCount();
- if (count > 0) {
- IImage image = list.getImageAt(count - 1);
- Uri uri = image.fullSizeImageUri();
- mThumbController.setData(uri, image.miniThumbBitmap());
- } else {
- mThumbController.setData(null, null);
- }
- list.close();
- }
-
private void showCameraErrorAndFinish() {
Resources ress = getResources();
Util.showFatalErrorAndFinish(Camera.this,
@@ -1691,53 +1854,6 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
clearFocusState();
}
- private Size getOptimalPreviewSize(List<Size> sizes, double targetRatio) {
- final double ASPECT_TOLERANCE = 0.05;
- if (sizes == null) return null;
-
- Size optimalSize = null;
- double minDiff = Double.MAX_VALUE;
-
- // Because of bugs of overlay and layout, we sometimes will try to
- // layout the viewfinder in the portrait orientation and thus get the
- // wrong size of mSurfaceView. When we change the preview size, the
- // new overlay will be created before the old one closed, which causes
- // an exception. For now, just get the screen size
-
- Display display = getWindowManager().getDefaultDisplay();
- int targetHeight = Math.min(display.getHeight(), display.getWidth());
-
- if (targetHeight <= 0) {
- // We don't know the size of SurefaceView, use screen height
- WindowManager windowManager = (WindowManager)
- getSystemService(Context.WINDOW_SERVICE);
- targetHeight = windowManager.getDefaultDisplay().getHeight();
- }
-
- // Try to find an size match aspect ratio and size
- for (Size size : sizes) {
- double ratio = (double) size.width / size.height;
- if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
- if (Math.abs(size.height - targetHeight) < minDiff) {
- optimalSize = size;
- minDiff = Math.abs(size.height - targetHeight);
- }
- }
-
- // Cannot find the one match the aspect ratio, ignore the requirement
- if (optimalSize == null) {
- Log.v(TAG, "No preview size match the aspect ratio");
- minDiff = Double.MAX_VALUE;
- for (Size size : sizes) {
- if (Math.abs(size.height - targetHeight) < minDiff) {
- optimalSize = size;
- minDiff = Math.abs(size.height - targetHeight);
- }
- }
- }
- return optimalSize;
- }
-
private static boolean isSupported(String value, List<String> supported) {
return supported == null ? false : supported.indexOf(value) >= 0;
}
@@ -1781,7 +1897,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
// Set a preview size that is closest to the viewfinder height and has
// the right aspect ratio.
List<Size> sizes = mParameters.getSupportedPreviewSizes();
- Size optimalSize = getOptimalPreviewSize(
+ Size optimalSize = Util.getOptimalPreviewSize(this,
sizes, (double) size.width / size.height);
if (optimalSize != null) {
Size original = mParameters.getPreviewSize();
@@ -1852,6 +1968,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
}
if (mHeadUpDisplay != null) updateSceneModeInHud();
+ // TODO: update icons on control panel.
if (Parameters.SCENE_MODE_AUTO.equals(mSceneMode)) {
// Set flash mode.
@@ -1945,21 +2062,22 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
MenuHelper.gotoCameraImageGallery(this);
}
- private void viewLastImage() {
- if (mThumbController.isUriValid()) {
- Intent intent = new Intent(Util.REVIEW_ACTION, mThumbController.getUri());
+ private void viewImage(RotateImageView view) {
+ if(!view.isUriValid()) {
+ Log.e(TAG, "Uri invalid. uri=" + view.getUri());
+ return;
+ }
+
+ try {
+ startActivity(new Intent(
+ Util.REVIEW_ACTION, view.getUri()));
+ } catch (ActivityNotFoundException ex) {
try {
- startActivity(intent);
- } catch (ActivityNotFoundException ex) {
- try {
- intent = new Intent(Intent.ACTION_VIEW, mThumbController.getUri());
- startActivity(intent);
- } catch (ActivityNotFoundException e) {
- Log.e(TAG, "review image fail", e);
- }
+ startActivity(new Intent(
+ Intent.ACTION_VIEW, view.getUri()));
+ } catch (ActivityNotFoundException e) {
+ Log.e(TAG, "review image fail. uri=" + view.getUri(), e);
}
- } else {
- Log.e(TAG, "Can't view last image.");
}
}
@@ -2201,7 +2319,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
private class MyHeadUpDisplayListener implements HeadUpDisplay.Listener {
- public void onSharedPreferencesChanged() {
+ public void onSharedPreferenceChanged() {
Camera.this.onSharedPreferenceChanged();
}
@@ -2217,7 +2335,9 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
if (mPausing) return;
Runnable runnable = new Runnable() {
public void run() {
- mHeadUpDisplay.restorePreferences(mParameters);
+ if (mHeadUpDisplay != null) {
+ mHeadUpDisplay.restorePreferences(mParameters);
+ }
}
};
MenuHelper.confirmAction(this,
@@ -2225,6 +2345,12 @@ public class Camera extends NoSearchActivity implements View.OnClickListener,
getString(R.string.confirm_restore_message),
runnable);
}
+
+ private class MyControlPanelListener implements ControlPanel.Listener {
+ public void onSharedPreferenceChanged() {
+ Camera.this.onSharedPreferenceChanged();
+ }
+ }
}
class FocusRectangle extends View {