diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2008-12-17 18:05:54 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2008-12-17 18:05:54 -0800 |
commit | 0eaec58e292ce4eaa6baadecf643f0f65e48d278 (patch) | |
tree | 78ef71512fa619ca4befa57b239be433f6aae74e /src/com/android/camera/VideoCamera.java | |
parent | 1d4c75065966c4f6f56900e31f655bfd1b334435 (diff) | |
download | LegacyCamera-0eaec58e292ce4eaa6baadecf643f0f65e48d278.zip LegacyCamera-0eaec58e292ce4eaa6baadecf643f0f65e48d278.tar.gz LegacyCamera-0eaec58e292ce4eaa6baadecf643f0f65e48d278.tar.bz2 |
Code drop from //branches/cupcake/...@124589
Diffstat (limited to 'src/com/android/camera/VideoCamera.java')
-rw-r--r-- | src/com/android/camera/VideoCamera.java | 810 |
1 files changed, 810 insertions, 0 deletions
diff --git a/src/com/android/camera/VideoCamera.java b/src/com/android/camera/VideoCamera.java new file mode 100644 index 0000000..7fcab9a --- /dev/null +++ b/src/com/android/camera/VideoCamera.java @@ -0,0 +1,810 @@ +/* + * Copyright (C) 2007 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; + +import java.io.File; +import java.util.ArrayList; +import java.io.IOException; + +import android.app.Activity; +import android.app.ProgressDialog; +import android.content.ActivityNotFoundException; +import android.content.BroadcastReceiver; +import android.content.ContentResolver; +import android.content.ContentValues; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.SharedPreferences; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.drawable.ColorDrawable; +import android.location.LocationManager; +import android.media.MediaMetadataRetriever; +import android.media.MediaRecorder; +import android.net.Uri; +import android.os.Bundle; +import android.os.Environment; +import android.os.Handler; +import android.os.Message; +import android.os.StatFs; +import android.os.SystemClock; +import android.preference.PreferenceManager; +import android.provider.MediaStore.Images; +import android.provider.MediaStore.Video; +import android.text.format.DateFormat; +import android.util.Log; +import android.view.KeyEvent; +import android.view.Menu; +import android.view.MenuItem; +import android.view.MotionEvent; +import android.view.SurfaceHolder; +import android.view.SurfaceView; +import android.view.View; +import android.view.Window; +import android.view.WindowManager; +import android.view.MenuItem.OnMenuItemClickListener; +import android.view.animation.Animation; +import android.widget.ImageView; +import android.widget.TextView; +import android.widget.Toast; +import android.widget.RelativeLayout.LayoutParams; + +public class VideoCamera extends Activity implements View.OnClickListener, SurfaceHolder.Callback { + + private static final String TAG = "videocamera"; + + private static final boolean DEBUG = true; + private static final boolean DEBUG_SUPPRESS_AUDIO_RECORDING = DEBUG && true; + private static final boolean DEBUG_DO_NOT_REUSE_MEDIA_RECORDER = DEBUG && true; + + private static final int KEEP = 2; + private static final int CLEAR_SCREEN_DELAY = 4; + private static final int UPDATE_RECORD_TIME = 5; + private static final int RESTART_PREVIEW = 6; + + private static final int SCREEN_DELAY = 2 * 60 * 1000; + private static final int POST_PICTURE_ALERT_TIMEOUT = 6 * 1000; + + private static final int NO_STORAGE_ERROR = -1; + private static final int CANNOT_STAT_ERROR = -2; + + public static final int MENU_SWITCH_TO_VIDEO = 0; + public static final int MENU_SWITCH_TO_CAMERA = 1; + public static final int MENU_SETTINGS = 6; + public static final int MENU_GALLERY_PHOTOS = 7; + public static final int MENU_GALLERY_VIDEOS = 8; + public static final int MENU_SAVE_SELECT_PHOTOS = 30; + public static final int MENU_SAVE_NEW_PHOTO = 31; + public static final int MENU_SAVE_SELECTVIDEO = 32; + public static final int MENU_SAVE_TAKE_NEW_VIDEO = 33; + public static final int MENU_SAVE_GALLERY_PHOTO = 34; + public static final int MENU_SAVE_GALLERY_VIDEO_PHOTO = 35; + public static final int MENU_SAVE_CAMERA_DONE = 36; + public static final int MENU_SAVE_CAMERA_VIDEO_DONE = 37; + + Toast mToast; + SharedPreferences mPreferences; + + private static final float VIDEO_ASPECT_RATIO = 176.0f / 144.0f; + VideoPreview mVideoPreview; + SurfaceHolder mSurfaceHolder = null; + ImageView mBlackout = null; + ImageView mVideoFrame; + Bitmap mVideoFrameBitmap; + + private MediaRecorder mMediaRecorder; + private boolean mMediaRecorderRecording = false; + private long mRecordingStartTime; + private String mCurrentVideoFilename; + private Uri mCurrentVideoUri; + + boolean mPausing = false; + + static ContentResolver mContentResolver; + boolean mDidRegister = false; + + int mCurrentZoomIndex = 0; + + private ImageView mModeIndicatorView; + private ImageView mRecordingIndicatorView; + private TextView mRecordingTimeView; + + ArrayList<MenuItem> mGalleryItems = new ArrayList<MenuItem>(); + + View mPostPictureAlert; + LocationManager mLocationManager = null; + + private int mPicturesRemaining; + + private Handler mHandler = new MainHandler(); + + private void cancelSavingNotification() { + if (mToast != null) { + mToast.cancel(); + mToast = null; + } + } + + /** This Handler is used to post message back onto the main thread of the application */ + private class MainHandler extends Handler { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case KEEP: { + keep(); + + if (msg.obj != null) { + mHandler.post((Runnable)msg.obj); + } + break; + } + + case CLEAR_SCREEN_DELAY: { + getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + break; + } + + case UPDATE_RECORD_TIME: { + if (mMediaRecorderRecording) { + long now = SystemClock.uptimeMillis(); + long delta = now - mRecordingStartTime; + long seconds = delta / 1000; + long minutes = seconds / 60; + long remainderSeconds = seconds - (minutes * 60); + + String secondsString = Long.toString(remainderSeconds); + if (secondsString.length() < 2) { + secondsString = "0" + secondsString; + } + String minutesString = Long.toString(minutes); + if (minutesString.length() < 2) { + minutesString = "0" + minutesString; + } + String text = minutesString + ":" + secondsString; + mRecordingTimeView.setText(text); + mHandler.sendEmptyMessageDelayed(UPDATE_RECORD_TIME, 1000); + } + break; + } + + case RESTART_PREVIEW: + hideVideoFrameAndStartPreview(); + break; + + default: + Log.v(TAG, "Unhandled message: " + msg.what); + break; + } + } + }; + + private final BroadcastReceiver mReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (action.equals(Intent.ACTION_MEDIA_MOUNTED)) { + // SD card available + // 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)) { + // SD card unavailable + showStorageToast(); + } else if (action.equals(Intent.ACTION_MEDIA_SCANNER_STARTED)) { + Toast.makeText(VideoCamera.this, getResources().getString(R.string.wait), 5000); + } else if (action.equals(Intent.ACTION_MEDIA_SCANNER_FINISHED)) { + showStorageToast(); + } + } + }; + + static private String createName(long dateTaken) { + return DateFormat.format("yyyy-MM-dd kk.mm.ss", dateTaken).toString(); + } + + private void postAfterKeep(final Runnable r) { + Message msg = mHandler.obtainMessage(KEEP); + msg.obj = r; + msg.sendToTarget(); + } + + /** Called with the activity is first created. */ + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + + mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); + + mPreferences = PreferenceManager.getDefaultSharedPreferences(this); + mContentResolver = getContentResolver(); + + //setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT); + requestWindowFeature(Window.FEATURE_PROGRESS); + + Window win = getWindow(); + win.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + setContentView(R.layout.video_camera); + + mVideoPreview = (VideoPreview) findViewById(R.id.camera_preview); + mVideoPreview.setAspectRatio(VIDEO_ASPECT_RATIO); + + // don't set mSurfaceHolder here. We have it set ONLY within + // surfaceCreated / surfaceDestroyed, other parts of the code + // assume that when it is set, the surface is also set. + SurfaceHolder holder = mVideoPreview.getHolder(); + holder.addCallback(this); + holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); + + mBlackout = (ImageView) findViewById(R.id.blackout); + mBlackout.setBackgroundDrawable(new ColorDrawable(0xFF000000)); + + mPostPictureAlert = findViewById(R.id.post_picture_panel); + View b; + + b = findViewById(R.id.play); + b.setOnClickListener(this); + + b = findViewById(R.id.share); + b.setOnClickListener(this); + + b = findViewById(R.id.discard); + b.setOnClickListener(this); + + mModeIndicatorView = (ImageView) findViewById(R.id.mode_indicator); + mRecordingIndicatorView = (ImageView) findViewById(R.id.recording_indicator); + mRecordingTimeView = (TextView) findViewById(R.id.recording_time); + mVideoFrame = (ImageView) findViewById(R.id.video_frame); + } + + @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) { + 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(); + } + }); + } + } + }); + t.start(); + } + + public void onClick(View v) { + switch (v.getId()) { + case R.id.discard: { + File f = new File(mCurrentVideoFilename); + f.delete(); + mContentResolver.delete(mCurrentVideoUri, null, null); + + hideVideoFrameAndStartPreview(); + break; + } + + case R.id.share: { + Intent intent = new Intent(); + intent.setAction(Intent.ACTION_SEND); + intent.setType("video/3gpp"); + intent.putExtra(Intent.EXTRA_STREAM, mCurrentVideoUri); + try { + startActivity(Intent.createChooser(intent, getText(R.string.sendVideo))); + } catch (android.content.ActivityNotFoundException ex) { + Toast.makeText(VideoCamera.this, R.string.no_way_to_share_video, Toast.LENGTH_SHORT).show(); + } + + break; + } + + case R.id.play: { + Intent intent = new Intent(Intent.ACTION_VIEW, mCurrentVideoUri); + try { + startActivity(intent); + } catch (android.content.ActivityNotFoundException ex) { + Log.e(TAG, "Couldn't view video " + mCurrentVideoUri, ex); + } + break; + } + } + } + + private void showStorageToast() { + String noStorageText = null; + int remaining = calculatePicturesRemaining(); + + if (remaining == NO_STORAGE_ERROR) { + noStorageText = getString(R.string.no_storage); + } else if (remaining < 1) { + noStorageText = getString(R.string.not_enough_space); + } + + if (noStorageText != null) { + Toast.makeText(this, noStorageText, 5000).show(); + } + } + + @Override + public void onResume() { + super.onResume(); + mHandler.sendEmptyMessageDelayed(CLEAR_SCREEN_DELAY, SCREEN_DELAY); + + mPausing = false; + + // install an intent filter to receive SD card related events. + IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MEDIA_MOUNTED); + intentFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED); + intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_STARTED); + intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED); + intentFilter.addDataScheme("file"); + registerReceiver(mReceiver, intentFilter); + mDidRegister = true; + + mBlackout.setVisibility(View.INVISIBLE); + if (mVideoFrameBitmap == null) { + initializeVideo(); + } else { + showPostRecordingAlert(); + } + } + + @Override + public void onStop() { + Log.v(TAG, "onStop"); + stopVideoRecording(); + keep(); + mHandler.removeMessages(CLEAR_SCREEN_DELAY); + super.onStop(); + } + + @Override + protected void onPause() { + Log.v(TAG, "onPause"); + stopVideoRecording(); + keep(); + hidePostPictureAlert(); + + mPausing = true; + + if (mDidRegister) { + unregisterReceiver(mReceiver); + mDidRegister = false; + } + + super.onPause(); + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + mHandler.sendEmptyMessageDelayed(CLEAR_SCREEN_DELAY, SCREEN_DELAY); + getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + + switch (keyCode) { + case KeyEvent.KEYCODE_BACK: + if (mMediaRecorderRecording) { + Log.v(TAG, "onKeyBack"); + stopVideoRecordingAndDisplayDialog(); + return true; + } else if(isPostRecordingAlertVisible()) { + hideVideoFrameAndStartPreview(); + return true; + } + break; + case KeyEvent.KEYCODE_FOCUS: + return true; + case KeyEvent.KEYCODE_CAMERA: + case KeyEvent.KEYCODE_DPAD_CENTER: + if (event.getRepeatCount() == 0) { + if (!mMediaRecorderRecording) { + startVideoRecording(); + } else { + stopVideoRecordingAndDisplayDialog(); + } + return true; + } + return true; + case KeyEvent.KEYCODE_MENU: + if (mMediaRecorderRecording) { + stopVideoRecordingAndDisplayDialog(); + return true; + } + hideVideoFrameAndStartPreview(); + break; + } + + return super.onKeyDown(keyCode, event); + } + + @Override + public boolean onTrackballEvent(MotionEvent event) { + cancelRestartPreviewTimeout(); + return super.onTrackballEvent(event); + } + + public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { + stopVideoRecording(); + initializeVideo(); + } + + public void surfaceCreated(SurfaceHolder holder) { + mSurfaceHolder = holder; + } + + public void surfaceDestroyed(SurfaceHolder holder) { + mSurfaceHolder = null; + } + + void gotoGallery() { + Uri target = Video.Media.INTERNAL_CONTENT_URI; + Intent intent = new Intent(Intent.ACTION_VIEW, target); + try { + startActivity(intent); + } catch (ActivityNotFoundException e) { + Log.e(TAG, "Could not start gallery activity", e); + } + } + + void keep() { + cancelSavingNotification(); + }; + + void toss() { + cancelSavingNotification(); + }; + + @Override + public boolean onPrepareOptionsMenu(Menu menu) { + super.onPrepareOptionsMenu(menu); + + for (int i = 1; i <= MenuHelper.MENU_ITEM_MAX; i++) { + if (i != MenuHelper.GENERIC_ITEM) { + menu.setGroupVisible(i, false); + } + } + + menu.setGroupVisible(MenuHelper.VIDEO_MODE_ITEM, true); + + return true; + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + super.onCreateOptionsMenu(menu); + + addBaseMenuItems(menu); + MenuHelper.addImageMenuItems( + menu, + MenuHelper.INCLUDE_ALL & ~MenuHelper.INCLUDE_ROTATE_MENU, + false, + VideoCamera.this, + mHandler, + + // Handler for deletion + new Runnable() { + public void run() { + // What do we do here? + // mContentResolver.delete(uri, null, null); + } + }, + new MenuHelper.MenuInvoker() { + public void run(final MenuHelper.MenuCallback cb) { + } + }); + + MenuItem gallery = menu.add(MenuHelper.IMAGE_SAVING_ITEM, MENU_SAVE_GALLERY_PHOTO, 0, + R.string.camera_gallery_photos_text).setOnMenuItemClickListener( + new MenuItem.OnMenuItemClickListener() { + public boolean onMenuItemClick(MenuItem item) { + postAfterKeep(new Runnable() { + public void run() { + gotoGallery(); + } + }); + return true; + } + }); + gallery.setIcon(android.R.drawable.ic_menu_gallery); + return true; + } + + private int calculatePicturesRemaining() { + try { + if (!ImageManager.hasStorage()) { + mPicturesRemaining = NO_STORAGE_ERROR; + } else { + String storageDirectory = Environment.getExternalStorageDirectory().toString(); + StatFs stat = new StatFs(storageDirectory); + float remaining = ((float)stat.getAvailableBlocks() * (float)stat.getBlockSize()) / 400000F; + mPicturesRemaining = (int)remaining; + } + } catch (Exception ex) { + // if we can't stat the filesystem then we don't know how many + // pictures are remaining. it might be zero but just leave it + // blank since we really don't know. + mPicturesRemaining = CANNOT_STAT_ERROR; + } + return mPicturesRemaining; + } + + private void initializeVideo() { + Log.v(TAG, "initializeVideo"); + releaseMediaRecorder(); + + if (mSurfaceHolder == null) { + Log.v(TAG, "SurfaceHolder is null"); + return; + } + + mMediaRecorder = new MediaRecorder(); + + if (DEBUG_SUPPRESS_AUDIO_RECORDING) { + Log.v(TAG, "DEBUG_SUPPRESS_AUDIO_RECORDING is true."); + } else { + mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); + } + mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); + mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); + Log.v(TAG, "before setOutputFile"); + createVideoPath(); + mMediaRecorder.setOutputFile(mCurrentVideoFilename); + Boolean videoQualityLow = getIntPreference("pref_camera_videoquality_key") == 0; + + // Use the same frame rate for both, since internally + // if the frame rate is too large, it can cause camera to become + // unstable. We need to fix the MediaRecorder to disable the support + // of setting frame rate for now. + mMediaRecorder.setVideoFrameRate(20); + if (videoQualityLow) { + mMediaRecorder.setVideoSize(176,144); + } else { + mMediaRecorder.setVideoSize(352,288); + } + mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263); + if (!DEBUG_SUPPRESS_AUDIO_RECORDING) { + mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); + } + Log.v(TAG, "before setPreviewDisplay"); + mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface()); + try { + mMediaRecorder.prepare(); + } catch (IOException exception) { + Log.e(TAG, "prepare failed for " + mCurrentVideoFilename); + releaseMediaRecorder(); + // TODO: add more exception handling logic here + return; + } + mMediaRecorderRecording = false; + } + + private void releaseMediaRecorder() { + Log.v(TAG, "Releasing media recorder."); + if (mMediaRecorder != null) { + mMediaRecorder.reset(); + mMediaRecorder.release(); + mMediaRecorder = null; + } + } + + private void restartPreview() { + if (DEBUG_DO_NOT_REUSE_MEDIA_RECORDER) { + Log.v(TAG, "DEBUG_DO_NOT_REUSE_MEDIA_RECORDER recreating mMediaRecorder."); + initializeVideo(); + } else { + try { + mMediaRecorder.prepare(); + } catch (IOException exception) { + Log.e(TAG, "prepare failed for " + mCurrentVideoFilename); + releaseMediaRecorder(); + // TODO: add more exception handling logic here + } + } + } + + private int getIntPreference(String key) { + String s = mPreferences.getString(key, "0"); + return Integer.parseInt(s); + } + + private void createVideoPath() { + long dateTaken = System.currentTimeMillis(); + String title = createName(dateTaken); + String displayName = title + ".3gp"; // Used when emailing. + String filename = ImageManager.CAMERA_IMAGE_BUCKET_NAME + "/" + + Long.toString(dateTaken) + ".3gp"; + ContentValues values = new ContentValues(7); + values.put(Video.Media.TITLE, title); + values.put(Video.Media.DISPLAY_NAME, displayName); + values.put(Video.Media.DESCRIPTION, ""); + values.put(Video.Media.DATE_TAKEN, dateTaken); + values.put(Video.Media.MIME_TYPE, "video/3gpp"); + values.put(Video.Media.DATA, filename); + Uri videoTable = Uri.parse("content://media/external/video/media"); + Uri item = mContentResolver.insert(videoTable, values); + mCurrentVideoFilename = filename; + mCurrentVideoUri = item; + } + + private void addBaseMenuItems(Menu menu) { + MenuHelper.addSwitchModeMenuItem(menu, this, false); + { + MenuItem gallery = menu.add(MenuHelper.IMAGE_MODE_ITEM, MENU_GALLERY_PHOTOS, 0, R.string.camera_gallery_photos_text).setOnMenuItemClickListener(new OnMenuItemClickListener() { + public boolean onMenuItemClick(MenuItem item) { + gotoGallery(); + return true; + } + }); + gallery.setIcon(android.R.drawable.ic_menu_gallery); + mGalleryItems.add(gallery); + } + { + MenuItem gallery = menu.add(MenuHelper.VIDEO_MODE_ITEM, MENU_GALLERY_VIDEOS, 0, R.string.camera_gallery_photos_text).setOnMenuItemClickListener(new OnMenuItemClickListener() { + public boolean onMenuItemClick(MenuItem item) { + gotoGallery(); + return true; + } + }); + gallery.setIcon(android.R.drawable.ic_menu_gallery); + mGalleryItems.add(gallery); + } + + MenuItem item = menu.add(MenuHelper.GENERIC_ITEM, MENU_SETTINGS, 0, R.string.settings).setOnMenuItemClickListener(new OnMenuItemClickListener() { + public boolean onMenuItemClick(MenuItem item) { + Intent intent = new Intent(); + intent.setClass(VideoCamera.this, CameraSettings.class); + startActivity(intent); + return true; + } + }); + item.setIcon(android.R.drawable.ic_menu_preferences); + } + + private void startVideoRecording() { + Log.v(TAG, "startVideoRecording"); + if (!mMediaRecorderRecording) { + + // Check mMediaRecorder to see whether it is initialized or not. + if (mMediaRecorder == null) { + initializeVideo(); + } + getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + try { + mMediaRecorder.start(); // Recording is now started + } catch (RuntimeException e) { + Log.e(TAG, "Could not start media recorder. ", e); + return; + } + mMediaRecorderRecording = true; + mRecordingStartTime = SystemClock.uptimeMillis(); + mModeIndicatorView.setVisibility(View.GONE); + mRecordingIndicatorView.setVisibility(View.VISIBLE); + mRecordingTimeView.setText(""); + mRecordingTimeView.setVisibility(View.VISIBLE); + mHandler.sendEmptyMessage(UPDATE_RECORD_TIME); + } + } + + private void stopVideoRecordingAndDisplayDialog() { + Log.v(TAG, "stopVideoRecordingAndDisplayDialog"); + if (mMediaRecorderRecording) { + stopVideoRecording(); + acquireAndShowVideoFrame(); + showPostRecordingAlert(); + } + } + + private void showPostRecordingAlert() { + cancelRestartPreviewTimeout(); + mPostPictureAlert.setVisibility(View.VISIBLE); + mHandler.sendEmptyMessageDelayed(RESTART_PREVIEW, POST_PICTURE_ALERT_TIMEOUT); + } + + private void hidePostPictureAlert() { + cancelRestartPreviewTimeout(); + mPostPictureAlert.setVisibility(View.INVISIBLE); + } + + private void cancelRestartPreviewTimeout() { + mHandler.removeMessages(RESTART_PREVIEW); + } + + private boolean isPostRecordingAlertVisible() { + return mPostPictureAlert.getVisibility() == View.VISIBLE; + } + + private void stopVideoRecording() { + Log.v(TAG, "stopVideoRecording"); + if (mMediaRecorderRecording || mMediaRecorder != null) { + if (mMediaRecorderRecording) { + mMediaRecorder.stop(); + } + releaseMediaRecorder(); + mMediaRecorderRecording = false; + mModeIndicatorView.setVisibility(View.VISIBLE); + mRecordingIndicatorView.setVisibility(View.GONE); + mRecordingTimeView.setVisibility(View.GONE); + getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + } + } + + private void hideVideoFrameAndStartPreview() { + hidePostPictureAlert(); + hideVideoFrame(); + restartPreview(); + } + + private void acquireAndShowVideoFrame() { + recycleVideoFrameBitmap(); + mVideoFrameBitmap = createVideoThumbnail(mCurrentVideoFilename); + mVideoFrame.setImageBitmap(mVideoFrameBitmap); + mVideoFrame.setVisibility(View.VISIBLE); + } + + private void hideVideoFrame() { + recycleVideoFrameBitmap(); + mVideoFrame.setVisibility(View.GONE); + } + + private void recycleVideoFrameBitmap() { + if (mVideoFrameBitmap != null) { + mVideoFrame.setImageDrawable(null); + mVideoFrameBitmap.recycle(); + mVideoFrameBitmap = null; + } + } + + private Bitmap createVideoThumbnail(String filePath) { + Bitmap bitmap = null; + MediaMetadataRetriever retriever = new MediaMetadataRetriever(); + try { + retriever.setMode(MediaMetadataRetriever.MODE_CAPTURE_FRAME_ONLY); + retriever.setDataSource(filePath); + bitmap = retriever.captureFrame(); + } finally { + retriever.release(); + } + return bitmap; + } + +} + |