diff options
Diffstat (limited to 'src/com/android/camera/Camera.java')
-rw-r--r-- | src/com/android/camera/Camera.java | 538 |
1 files changed, 315 insertions, 223 deletions
diff --git a/src/com/android/camera/Camera.java b/src/com/android/camera/Camera.java index 11b1ccd..a6775ae 100644 --- a/src/com/android/camera/Camera.java +++ b/src/com/android/camera/Camera.java @@ -34,6 +34,7 @@ import android.content.SharedPreferences; import android.content.pm.ActivityInfo; import android.content.res.AssetFileDescriptor; import android.content.res.Resources; +import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Matrix; @@ -41,6 +42,7 @@ import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.LayerDrawable; +import android.graphics.drawable.TransitionDrawable; import android.hardware.Camera.PictureCallback; import android.hardware.Camera.Size; import android.location.Location; @@ -73,6 +75,7 @@ import android.view.Window; import android.view.WindowManager; import android.view.MenuItem.OnMenuItemClickListener; import android.view.ViewGroup.LayoutParams; +import android.view.animation.AlphaAnimation; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.widget.ImageView; @@ -86,6 +89,8 @@ public class Camera extends Activity implements View.OnClickListener, private static final String TAG = "camera"; private static final boolean DEBUG = false; + private static final boolean DEBUG_TIME_OPERATIONS = DEBUG && false; + private static final boolean DEBUG_FAKE_GPS_LOCATION = DEBUG && false; private static final int CROP_MSG = 1; private static final int KEEP = 2; @@ -124,6 +129,7 @@ public class Camera extends Activity implements View.OnClickListener, private static final String sTempCropFilename = "crop-temp"; private android.hardware.Camera mCameraDevice; + private android.hardware.Camera.Parameters mParameters; private VideoPreview mSurfaceView; private SurfaceHolder mSurfaceHolder = null; private ImageView mBlackout = null; @@ -152,6 +158,12 @@ public class Camera extends Activity implements View.OnClickListener, private boolean mMenuSelectionMade; private ImageView mLastPictureButton; + private LayerDrawable mVignette; + private Animation mShowLastPictureButtonAnimation = new AlphaAnimation(0F, 1F); + private boolean mShouldShowLastPictureButton; + private TransitionDrawable mThumbnailTransition; + private Drawable[] mThumbnails; + private boolean mShouldTransitionThumbnails; private Uri mLastPictureUri; private LocationManager mLocationManager = null; @@ -170,6 +182,9 @@ public class Camera extends Activity implements View.OnClickListener, private boolean mKeepAndRestartPreview; + private View mPostCaptureAlert; + + private Handler mHandler = new MainHandler(); private ProgressDialog mSavingProgress; @@ -217,6 +232,7 @@ public class Camera extends Activity implements View.OnClickListener, mHandler.sendEmptyMessageDelayed(RESTART_PREVIEW, 100); } else if (mStatus == SNAPSHOT_COMPLETED){ mCaptureObject.dismissFreezeFrame(true); + hidePostCaptureAlert(); } break; } @@ -244,9 +260,11 @@ public class Camera extends Activity implements View.OnClickListener, // TODO put up a "please wait" message // TODO also listen for the media scanner finished message showStorageToast(); - } else if (action.equals(Intent.ACTION_MEDIA_UNMOUNTED)) { + } else if (action.equals(Intent.ACTION_MEDIA_UNMOUNTED) || + action.equals(Intent.ACTION_MEDIA_CHECKING)) { // SD card unavailable - showStorageToast(); + mPicturesRemaining = MenuHelper.NO_STORAGE_ERROR; + showStorageToast(mPicturesRemaining); } else if (action.equals(Intent.ACTION_MEDIA_SCANNER_STARTED)) { Toast.makeText(Camera.this, getResources().getString(R.string.wait), 5000); } else if (action.equals(Intent.ACTION_MEDIA_SCANNER_FINISHED)) { @@ -298,7 +316,7 @@ public class Camera extends Activity implements View.OnClickListener, private final class ShutterCallback implements android.hardware.Camera.ShutterCallback { public void onShutter() { - if (DEBUG) { + if (DEBUG_TIME_OPERATIONS) { long now = System.currentTimeMillis(); Log.v(TAG, "********** Total shutter lag " + (now - mShutterPressTime) + " ms"); } @@ -314,7 +332,7 @@ public class Camera extends Activity implements View.OnClickListener, if (Config.LOGV) Log.v(TAG, "got RawPictureCallback..."); mRawPictureCallbackTime = System.currentTimeMillis(); - mBlackout.setVisibility(View.INVISIBLE); + mBlackout.setVisibility(View.GONE); } }; @@ -428,7 +446,7 @@ public class Camera extends Activity implements View.OnClickListener, private void storeImage(byte[] data, Location loc) { try { - if (DEBUG) { + if (DEBUG_TIME_OPERATIONS) { startTiming(); } long dateTaken = System.currentTimeMillis(); @@ -455,7 +473,7 @@ public class Camera extends Activity implements View.OnClickListener, mAddImageCancelable = null; } - if (DEBUG) { + if (DEBUG_TIME_OPERATIONS) { stopTiming(); Log.d(TAG, "Storing image took " + (mWallTimeEnd - mWallTimeStart) + " ms. " + "Thread time was " + ((mThreadTimeEnd - mThreadTimeStart) / 1000000) + @@ -472,19 +490,19 @@ public class Camera extends Activity implements View.OnClickListener, if (!captureOnly) { storeImage(data, loc); sendBroadcast(new Intent("com.android.camera.NEW_PICTURE", mLastContentUri)); - setLastPictureThumb(data); + setLastPictureThumb(data, mCaptureObject.getLastCaptureUri()); dismissFreezeFrame(true); } else { BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 4; - if (DEBUG) { + if (DEBUG_TIME_OPERATIONS) { startTiming(); } mCaptureOnlyBitmap = BitmapFactory.decodeByteArray(data, 0, data.length, options); - if (DEBUG) { + if (DEBUG_TIME_OPERATIONS) { stopTiming(); Log.d(TAG, "Decoded mCaptureOnly bitmap (" + mCaptureOnlyBitmap.getWidth() + "x" + mCaptureOnlyBitmap.getHeight() + " ) in " + @@ -492,56 +510,16 @@ public class Camera extends Activity implements View.OnClickListener, ((mThreadTimeEnd - mThreadTimeStart) / 1000000) + " ms."); } - openOptionsMenu(); + showPostCaptureAlert(); + cancelAutomaticPreviewRestart(); } - mCapturing = false; if (mPausing) { closeCamera(); } } - private void setLastPictureThumb(byte[] data) { - BitmapFactory.Options options = new BitmapFactory.Options(); - options.inSampleSize = 16; - - if (DEBUG) { - startTiming(); - } - - Bitmap lastPictureThumb = BitmapFactory.decodeByteArray(data, 0, data.length, options); - - if (DEBUG) { - stopTiming(); - Log.d(TAG, "Decoded lastPictureThumb bitmap (" + lastPictureThumb.getWidth() + - "x" + lastPictureThumb.getHeight() + " ) in " + - (mWallTimeEnd - mWallTimeStart) + " ms. Thread time was " + - ((mThreadTimeEnd - mThreadTimeStart) / 1000000) + " ms."); - } - - final int PADDING_WIDTH = 2; - final int PADDING_HEIGHT = 2; - LayoutParams layoutParams = mLastPictureButton.getLayoutParams(); - // Make the mini-thumbnail size smaller than the button size so that the image corners - // don't peek out from the rounded corners of the frame_thumbnail graphic: - final int miniThumbWidth = layoutParams.width - 2 * PADDING_WIDTH; - final int miniThumbHeight = layoutParams.height - 2 * PADDING_HEIGHT; - - lastPictureThumb = ImageManager.extractMiniThumb(lastPictureThumb, - miniThumbWidth, miniThumbHeight); - - Drawable[] layers = new Drawable[2]; - layers[0] = new BitmapDrawable(lastPictureThumb); - layers[1] = getResources().getDrawable(R.drawable.frame_thumbnail); - LayerDrawable layerDrawable = new LayerDrawable(layers); - layerDrawable.setLayerInset(0, PADDING_WIDTH, PADDING_HEIGHT, - PADDING_WIDTH, PADDING_HEIGHT); - mLastPictureButton.setImageDrawable(layerDrawable); - mLastPictureButton.setVisibility(View.VISIBLE); - mLastPictureUri = mCaptureObject.getLastCaptureUri(); - } - /* * Tells the image capture thread to abort the capture of the * current image. @@ -589,44 +567,63 @@ public class Camera extends Activity implements View.OnClickListener, Boolean recordLocation = mPreferences.getBoolean("pref_camera_recordlocation_key", false); Location loc = recordLocation ? getCurrentLocation() : null; - android.hardware.Camera.Parameters parameters = mCameraDevice.getParameters(); // Quality 75 has visible artifacts, and quality 90 looks great but the files begin to // get large. 85 is a good compromise between the two. - parameters.set("jpeg-quality", 85); - parameters.set("rotation", latchedOrientation); - - parameters.remove("gps-latitude"); - parameters.remove("gps-longitude"); - parameters.remove("gps-altitude"); - parameters.remove("gps-timestamp"); - - if (loc != null) { + mParameters.set("jpeg-quality", 85); + mParameters.set("rotation", latchedOrientation); + + mParameters.remove("gps-latitude"); + mParameters.remove("gps-longitude"); + mParameters.remove("gps-altitude"); + mParameters.remove("gps-timestamp"); + + if (DEBUG_FAKE_GPS_LOCATION) { + // Google London office, having trouble encoding longitude + + if (false) { + // This fails: + mParameters.set("gps-latitude", "51.49473309516907"); + mParameters.set("gps-longitude", "-0.14598190784454346"); + mParameters.set("gps-altitude", "71.0"); // meters + mParameters.set("gps-timestamp", "1233744883"); + } else { + // This works OK: + mParameters.set("gps-latitude", "51.49473309516907"); + mParameters.set("gps-longitude", "-1.0"); + mParameters.set("gps-altitude", "71.0"); // meters + mParameters.set("gps-timestamp", "1233744883"); + } + } else if (loc != null) { double lat = loc.getLatitude(); double lon = loc.getLongitude(); + boolean hasLatLon = (lat != 0.0d) || (lon != 0.0d); - if (lat != 0D && lon != 0d) { - parameters.set("gps-latitude", String.valueOf(lat)); - parameters.set("gps-longitude", String.valueOf(lon)); + if (hasLatLon) { + String latString = String.valueOf(lat); + String lonString = String.valueOf(lon); + mParameters.set("gps-latitude", latString); + mParameters.set("gps-longitude", lonString); if (loc.hasAltitude()) - parameters.set("gps-altitude", String.valueOf(loc.getAltitude())); + mParameters.set("gps-altitude", String.valueOf(loc.getAltitude())); if (loc.getTime() != 0) { // Location.getTime() is UTC in milliseconds. // gps-timestamp is UTC in seconds. long utcTimeSeconds = loc.getTime() / 1000; - parameters.set("gps-timestamp", String.valueOf(utcTimeSeconds)); + mParameters.set("gps-timestamp", String.valueOf(utcTimeSeconds)); } } else { loc = null; } } - Size pictureSize = parameters.getPictureSize(); + + Size pictureSize = mParameters.getPictureSize(); // resize the SurfaceView to the aspect-ratio of the still image // and so that we can see the full image that was taken mSurfaceView.setAspectRatio(pictureSize.width, pictureSize.height); - mCameraDevice.setParameters(parameters); + mCameraDevice.setParameters(mParameters); mCameraDevice.takePicture(mShutterCallback, mRawPictureCallback, new JpegPictureCallback(loc)); @@ -653,9 +650,9 @@ public class Camera extends Activity implements View.OnClickListener, // Don't check the filesystem here, we can't afford the latency. Instead, check the // cached value which was calculated when the preview was restarted. - if (DEBUG) mShutterPressTime = System.currentTimeMillis(); + if (DEBUG_TIME_OPERATIONS) mShutterPressTime = System.currentTimeMillis(); if (mPicturesRemaining < 1) { - showStorageToast(); + showStorageToast(mPicturesRemaining); return; } @@ -672,6 +669,52 @@ public class Camera extends Activity implements View.OnClickListener, } } + private void setLastPictureThumb(byte[] data, Uri uri) { + BitmapFactory.Options options = new BitmapFactory.Options(); + options.inSampleSize = 16; + + Bitmap lastPictureThumb = BitmapFactory.decodeByteArray(data, 0, data.length, options); + + setLastPictureThumb(lastPictureThumb, uri); + } + + private void setLastPictureThumb(Bitmap lastPictureThumb, Uri uri) { + + final int PADDING_WIDTH = 2; + final int PADDING_HEIGHT = 2; + LayoutParams layoutParams = mLastPictureButton.getLayoutParams(); + // Make the mini-thumbnail size smaller than the button size so that the image corners + // don't peek out from the rounded corners of the frame_thumbnail graphic: + final int miniThumbWidth = layoutParams.width - 2 * PADDING_WIDTH; + final int miniThumbHeight = layoutParams.height - 2 * PADDING_HEIGHT; + + lastPictureThumb = ImageManager.extractMiniThumb(lastPictureThumb, + miniThumbWidth, miniThumbHeight); + + Drawable[] vignetteLayers = new Drawable[2]; + vignetteLayers[1] = getResources().getDrawable(R.drawable.frame_thumbnail); + if (mThumbnails == null) { + mThumbnails = new Drawable[2]; + mThumbnails[1] = new BitmapDrawable(lastPictureThumb); + vignetteLayers[0] = mThumbnails[1]; + } else { + mThumbnails[0] = mThumbnails[1]; + mThumbnails[1] = new BitmapDrawable(lastPictureThumb); + mThumbnailTransition = new TransitionDrawable(mThumbnails); + mShouldTransitionThumbnails = true; + vignetteLayers[0] = mThumbnailTransition; + } + + mVignette = new LayerDrawable(vignetteLayers); + mVignette.setLayerInset(0, PADDING_WIDTH, PADDING_HEIGHT, + PADDING_WIDTH, PADDING_HEIGHT); + mLastPictureButton.setImageDrawable(mVignette); + + if (mLastPictureButton.getVisibility() != View.VISIBLE) { + mShouldShowLastPictureButton = true; + } + mLastPictureUri = uri; + } static private String createName(long dateTaken) { return DateFormat.format("yyyy-MM-dd kk.mm.ss", dateTaken).toString(); @@ -741,10 +784,27 @@ public class Camera extends Activity implements View.OnClickListener, mBlackout.setBackgroundDrawable(new ColorDrawable(0xFF000000)); mLastPictureButton = (ImageView) findViewById(R.id.last_picture_button); - mLastPictureButton.setOnClickListener(this); - mLastPictureButton.setVisibility(View.INVISIBLE); + if (!isImageCaptureIntent()) { + ImageManager.IImageList images = ImageManager.instance().allImages( + this, + getContentResolver(), + ImageManager.DataLocation.ALL, + ImageManager.INCLUDE_IMAGES, + ImageManager.SORT_DESCENDING, + ImageManager.CAMERA_IMAGE_BUCKET_ID); + ImageManager.IImage lastPicture = + images.isEmpty() ? null : images.getImageAt(0); + mLastPictureButton.setOnClickListener(this); + if (lastPicture == null) { + mLastPictureButton.setVisibility(View.GONE); + } else { + Bitmap miniThumb = lastPicture.miniThumbBitmap(); + setLastPictureThumb(miniThumb, lastPicture.fullSizeImageUri()); + } + images.deactivate(); + } - mShutterButton = (ShutterButton) findViewById(R.id.mode_indicator); + mShutterButton = (ShutterButton) findViewById(R.id.shutter_button); mShutterButton.setOnShutterButtonListener(this); try { @@ -773,42 +833,22 @@ public class Camera extends Activity implements View.OnClickListener, mFocusBlinkAnimation = AnimationUtils.loadAnimation(this, R.anim.auto_focus_blink); mFocusBlinkAnimation.setRepeatCount(Animation.INFINITE); mFocusBlinkAnimation.setRepeatMode(Animation.REVERSE); + + mPostCaptureAlert = findViewById(R.id.post_picture_panel); } @Override public void onStart() { super.onStart(); - final View hintView = findViewById(R.id.hint_toast); - if (hintView != null) - hintView.setVisibility(View.GONE); - Thread t = new Thread(new Runnable() { public void run() { final boolean storageOK = calculatePicturesRemaining() > 0; - if (hintView == null) - return; - if (storageOK) { + if (!storageOK) { mHandler.post(new Runnable() { public void run() { - hintView.setVisibility(View.VISIBLE); - } - }); - mHandler.postDelayed(new Runnable() { - public void run() { - Animation a = new android.view.animation.AlphaAnimation(1F, 0F); - a.setDuration(500); - a.startNow(); - hintView.setAnimation(a); - hintView.setVisibility(View.GONE); - } - }, 3000); - } else { - mHandler.post(new Runnable() { - public void run() { - hintView.setVisibility(View.GONE); - showStorageToast(); + showStorageToast(mPicturesRemaining); } }); } @@ -822,12 +862,124 @@ public class Camera extends Activity implements View.OnClickListener, case R.id.last_picture_button: viewLastImage(); break; + case R.id.attach: + doAttach(); + break; + case R.id.cancel: + doCancel(); } } + private void doAttach() { + Bitmap bitmap = mImageCapture.getLastBitmap(); + mCaptureObject.setDone(true); + + String cropValue = null; + Uri saveUri = null; + + Bundle myExtras = getIntent().getExtras(); + if (myExtras != null) { + saveUri = (Uri) myExtras.getParcelable(MediaStore.EXTRA_OUTPUT); + cropValue = myExtras.getString("crop"); + } + + + if (cropValue == null) { + /* + * First handle the no crop case -- just return the value. If the caller + * specifies a "save uri" then write the data to it's stream. Otherwise, + * pass back a scaled down version of the bitmap directly in the extras. + */ + if (saveUri != null) { + OutputStream outputStream = null; + try { + outputStream = mContentResolver.openOutputStream(saveUri); + bitmap.compress(Bitmap.CompressFormat.JPEG, 75, outputStream); + outputStream.close(); + + setResult(RESULT_OK); + finish(); + } catch (IOException ex) { + // + } finally { + if (outputStream != null) { + try { + outputStream.close(); + } catch (IOException ex) { + + } + } + } + } else { + float scale = .5F; + Matrix m = new Matrix(); + m.setScale(scale, scale); + + bitmap = Bitmap.createBitmap(bitmap, 0, 0, + bitmap.getWidth(), + bitmap.getHeight(), + m, true); + + setResult(RESULT_OK, new Intent("inline-data").putExtra("data", bitmap)); + finish(); + } + } + else { + /* + * Save the image to a temp file and invoke the cropper + */ + Uri tempUri = null; + FileOutputStream tempStream = null; + try { + File path = getFileStreamPath(sTempCropFilename); + path.delete(); + tempStream = openFileOutput(sTempCropFilename, 0); + bitmap.compress(Bitmap.CompressFormat.JPEG, 75, tempStream); + tempStream.close(); + tempUri = Uri.fromFile(path); + } catch (FileNotFoundException ex) { + setResult(Activity.RESULT_CANCELED); + finish(); + return; + } catch (IOException ex) { + setResult(Activity.RESULT_CANCELED); + finish(); + return; + } finally { + if (tempStream != null) { + try { + tempStream.close(); + } catch (IOException ex) { + + } + } + } + + Bundle newExtras = new Bundle(); + if (cropValue.equals("circle")) + newExtras.putString("circleCrop", "true"); + if (saveUri != null) + newExtras.putParcelable(MediaStore.EXTRA_OUTPUT, saveUri); + else + newExtras.putBoolean("return-data", true); + + Intent cropIntent = new Intent(); + cropIntent.setClass(Camera.this, CropImage.class); + cropIntent.setData(tempUri); + cropIntent.putExtras(newExtras); + + startActivityForResult(cropIntent, CROP_MSG); + } + } + + private void doCancel() { + setResult(RESULT_CANCELED, new Intent()); + finish(); + } + public void onShutterButtonFocus(ShutterButton button, boolean pressed) { switch (button.getId()) { - case R.id.mode_indicator: + case R.id.shutter_button: doFocus(pressed); break; } @@ -835,7 +987,7 @@ public class Camera extends Activity implements View.OnClickListener, public void onShutterButtonClick(ShutterButton button) { switch (button.getId()) { - case R.id.mode_indicator: + case R.id.shutter_button: doSnap(false); break; } @@ -845,6 +997,10 @@ public class Camera extends Activity implements View.OnClickListener, MenuHelper.showStorageToast(this); } + private void showStorageToast(int remainingPictures) { + MenuHelper.showStorageToast(this, remainingPictures); + } + @Override public void onResume() { super.onResume(); @@ -858,6 +1014,7 @@ public class Camera extends Activity implements View.OnClickListener, intentFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED); intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_STARTED); intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED); + intentFilter.addAction(Intent.ACTION_MEDIA_CHECKING); intentFilter.addDataScheme("file"); registerReceiver(mReceiver, intentFilter); mDidRegister = true; @@ -878,14 +1035,14 @@ public class Camera extends Activity implements View.OnClickListener, mFocusToneGenerator = null; } - mBlackout.setVisibility(View.INVISIBLE); + mBlackout.setVisibility(View.GONE); if (mLastPictureUri != null) { IImageList list = ImageManager.makeImageList(mLastPictureUri, this, ImageManager.SORT_ASCENDING); if (list.getImageForUri(mLastPictureUri) == null) { mLastPictureUri = null; - mLastPictureButton.setVisibility(View.INVISIBLE); + mLastPictureButton.setVisibility(View.GONE); } list.deactivate(); } @@ -996,7 +1153,7 @@ public class Camera extends Activity implements View.OnClickListener, switch (keyCode) { case KeyEvent.KEYCODE_BACK: - if (mStatus == SNAPSHOT_IN_PROGRESS || mStatus == SNAPSHOT_COMPLETED) { + if (mStatus == SNAPSHOT_IN_PROGRESS) { // ignore backs while we're taking a picture return true; } @@ -1011,6 +1168,18 @@ public class Camera extends Activity implements View.OnClickListener, doSnap(false); } return true; + case KeyEvent.KEYCODE_DPAD_CENTER: + // If we get a dpad center event without any focused view, move the + // focus to the shutter button and press it. + if (event.getRepeatCount() == 0) { + if (mShutterButton.isInTouchMode()) { + mShutterButton.requestFocusFromTouch(); + } else { + mShutterButton.requestFocus(); + } + mShutterButton.setPressed(true); + } + return true; } return super.onKeyDown(keyCode, event); @@ -1053,6 +1222,7 @@ public class Camera extends Activity implements View.OnClickListener, private void doFocus(boolean pressed) { if (pressed) { mIsFocusButtonPressed = true; + mCaptureOnFocus = false; if (mPreviewing) { autoFocus(); } else if (mCaptureObject != null) { @@ -1113,6 +1283,17 @@ public class Camera extends Activity implements View.OnClickListener, // TODO: The best longterm solution is to write a reserve file of maximum JPEG size, always // let the user take a picture, and delete that file if needed to save the new photo. calculatePicturesRemaining(); + + if (mShouldShowLastPictureButton) { + mShouldShowLastPictureButton = false; + mLastPictureButton.setVisibility(View.VISIBLE); + Animation a = mShowLastPictureButtonAnimation; + a.setDuration(500); + mLastPictureButton.setAnimation(a); + } else if (mShouldTransitionThumbnails) { + mShouldTransitionThumbnails = false; + mThumbnailTransition.reverseTransition(500); + } } private void setViewFinder(int w, int h, boolean startPreview) { @@ -1169,10 +1350,10 @@ public class Camera extends Activity implements View.OnClickListener, // request the preview size, the hardware may not honor it, // if we depended on it we would have to query the size again - android.hardware.Camera.Parameters p = mCameraDevice.getParameters(); - p.setPreviewSize(w, h); + mParameters = mCameraDevice.getParameters(); + mParameters.setPreviewSize(w, h); try { - mCameraDevice.setParameters(p); + mCameraDevice.setParameters(mParameters); } catch (IllegalArgumentException e) { // Ignore this error, it happens in the simulator. } @@ -1266,6 +1447,7 @@ public class Camera extends Activity implements View.OnClickListener, ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); intent.putExtra(MediaStore.EXTRA_FULL_SCREEN, true); intent.putExtra(MediaStore.EXTRA_SHOW_ACTION_ICONS, true); + intent.putExtra("com.android.camera.ReviewMode", true); try { startActivity(intent); @@ -1374,8 +1556,7 @@ public class Camera extends Activity implements View.OnClickListener, public boolean onMenuOpened(int featureId, Menu menu) { if (featureId == Window.FEATURE_OPTIONS_PANEL) { if (mStatus == SNAPSHOT_IN_PROGRESS) { - mKeepAndRestartPreview = false; - mHandler.removeMessages(RESTART_PREVIEW); + cancelAutomaticPreviewRestart(); mMenuSelectionMade = false; } } @@ -1408,127 +1589,43 @@ public class Camera extends Activity implements View.OnClickListener, return true; } + private void cancelAutomaticPreviewRestart() { + mKeepAndRestartPreview = false; + mHandler.removeMessages(RESTART_PREVIEW); + } + private boolean isImageCaptureIntent() { String action = getIntent().getAction(); return (MediaStore.ACTION_IMAGE_CAPTURE.equals(action)); } + private void showPostCaptureAlert() { + boolean isPick = isImageCaptureIntent(); + int pickVisible = isPick ? View.VISIBLE : View.GONE; + mPostCaptureAlert.setVisibility(pickVisible); + if (isPick) { + int[] pickIds = {R.id.attach, R.id.cancel}; + for(int id : pickIds) { + View view = mPostCaptureAlert.findViewById(id); + view.setOnClickListener(this); + Animation animation = new AlphaAnimation(0F, 1F); + animation.setDuration(500); + view.setAnimation(animation); + } + } + } + + private void hidePostCaptureAlert() { + mPostCaptureAlert.setVisibility(View.GONE); + } + @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); if (isImageCaptureIntent()) { - menu.add(MenuHelper.IMAGE_SAVING_ITEM, MENU_SAVE_SELECT_PHOTOS , 0, R.string.camera_selectphoto).setOnMenuItemClickListener(new OnMenuItemClickListener() { - public boolean onMenuItemClick(MenuItem item) { - Bitmap bitmap = mImageCapture.getLastBitmap(); - mCaptureObject.setDone(true); - - String cropValue = null; - Uri saveUri = null; - - Bundle myExtras = getIntent().getExtras(); - if (myExtras != null) { - saveUri = (Uri) myExtras.getParcelable(MediaStore.EXTRA_OUTPUT); - cropValue = myExtras.getString("crop"); - } - - - if (cropValue == null) { - /* - * First handle the no crop case -- just return the value. If the caller - * specifies a "save uri" then write the data to it's stream. Otherwise, - * pass back a scaled down version of the bitmap directly in the extras. - */ - if (saveUri != null) { - OutputStream outputStream = null; - try { - outputStream = mContentResolver.openOutputStream(saveUri); - bitmap.compress(Bitmap.CompressFormat.JPEG, 75, outputStream); - outputStream.close(); - - setResult(RESULT_OK); - finish(); - } catch (IOException ex) { - // - } finally { - if (outputStream != null) { - try { - outputStream.close(); - } catch (IOException ex) { - - } - } - } - } else { - float scale = .5F; - Matrix m = new Matrix(); - m.setScale(scale, scale); - - bitmap = Bitmap.createBitmap(bitmap, 0, 0, - bitmap.getWidth(), - bitmap.getHeight(), - m, true); - - setResult(RESULT_OK, new Intent("inline-data").putExtra("data", bitmap)); - finish(); - } - } - else { - /* - * Save the image to a temp file and invoke the cropper - */ - Uri tempUri = null; - FileOutputStream tempStream = null; - try { - File path = getFileStreamPath(sTempCropFilename); - path.delete(); - tempStream = openFileOutput(sTempCropFilename, 0); - bitmap.compress(Bitmap.CompressFormat.JPEG, 75, tempStream); - tempStream.close(); - tempUri = Uri.fromFile(path); - } catch (FileNotFoundException ex) { - setResult(Activity.RESULT_CANCELED); - finish(); - return true; - } catch (IOException ex) { - setResult(Activity.RESULT_CANCELED); - finish(); - return true; - } finally { - if (tempStream != null) { - try { - tempStream.close(); - } catch (IOException ex) { - - } - } - } - - Bundle newExtras = new Bundle(); - if (cropValue.equals("circle")) - newExtras.putString("circleCrop", "true"); - if (saveUri != null) - newExtras.putParcelable(MediaStore.EXTRA_OUTPUT, saveUri); - else - newExtras.putBoolean("return-data", true); - - Intent cropIntent = new Intent(); - cropIntent.setClass(Camera.this, CropImage.class); - cropIntent.setData(tempUri); - cropIntent.putExtras(newExtras); - - startActivityForResult(cropIntent, CROP_MSG); - } - return true; - } - }); - - menu.add(MenuHelper.IMAGE_SAVING_ITEM, MENU_SAVE_NEW_PHOTO, 0, R.string.camera_takenewphoto).setOnMenuItemClickListener(new OnMenuItemClickListener() { - public boolean onMenuItemClick(MenuItem item) { - keep(); - return true; - } - }); + // No options menu for attach mode. + return false; } else { addBaseMenuItems(menu); MenuHelper.addImageMenuItems( @@ -1627,10 +1724,5 @@ public class Camera extends Activity implements View.OnClickListener, }); item.setIcon(android.R.drawable.ic_menu_preferences); } - - private void cancelRestartPreviewTimeout() { - mHandler.removeMessages(RESTART_PREVIEW); - } - } |