summaryrefslogtreecommitdiffstats
path: root/src/com/android/camera/VideoCamera.java
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2008-12-17 18:05:54 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2008-12-17 18:05:54 -0800
commit0eaec58e292ce4eaa6baadecf643f0f65e48d278 (patch)
tree78ef71512fa619ca4befa57b239be433f6aae74e /src/com/android/camera/VideoCamera.java
parent1d4c75065966c4f6f56900e31f655bfd1b334435 (diff)
downloadLegacyCamera-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.java810
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;
+ }
+
+}
+