VideoCamera.java revision de365d87520c97d6b1636442e6b5c82a3e036f29
1b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project/* 2b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 3b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * 4b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * you may not use this file except in compliance with the License. 6b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * You may obtain a copy of the License at 7b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * 8b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * 10b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * See the License for the specific language governing permissions and 14b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * limitations under the License. 15b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project */ 16b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 17b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectpackage com.android.camera; 18b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 19b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport java.io.File; 20b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport java.io.FileDescriptor; 21b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport java.io.IOException; 22b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport java.io.InputStream; 23b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport java.io.OutputStream; 24b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport java.text.SimpleDateFormat; 25b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport java.util.ArrayList; 26b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport java.util.Date; 27b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 28b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.app.Activity; 29b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.app.AlertDialog; 30b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.BroadcastReceiver; 31b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.ContentResolver; 32b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.ContentValues; 33b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.Context; 34b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.Intent; 35b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.IntentFilter; 36b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.SharedPreferences; 37b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.graphics.Bitmap; 38de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Projectimport android.graphics.BitmapFactory; 39de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Projectimport android.graphics.Canvas; 40de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Projectimport android.graphics.Matrix; 41de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Projectimport android.graphics.Paint; 42de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Projectimport android.graphics.PorterDuff; 43de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Projectimport android.graphics.PorterDuffXfermode; 44de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Projectimport android.graphics.RectF; 45b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.graphics.drawable.ColorDrawable; 46de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Projectimport android.graphics.drawable.BitmapDrawable; 47b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.graphics.drawable.Drawable; 48de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Projectimport android.graphics.drawable.LayerDrawable; 49de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Projectimport android.graphics.drawable.TransitionDrawable; 50b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.location.LocationManager; 51b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.media.MediaMetadataRetriever; 52b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.media.MediaRecorder; 53b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.net.Uri; 54b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.Bundle; 55b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.Environment; 56b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.Handler; 57b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.Message; 58b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.StatFs; 59b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.SystemClock; 60b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.preference.PreferenceManager; 61b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.provider.MediaStore; 62b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.provider.MediaStore.Video; 63b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.text.format.DateFormat; 64b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.util.Log; 65b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.KeyEvent; 66b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.Menu; 67b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.MenuItem; 68b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.SurfaceHolder; 69b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.View; 70de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Projectimport android.view.ViewGroup.LayoutParams; 71b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.Window; 72b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.WindowManager; 73b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.MenuItem.OnMenuItemClickListener; 74b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.animation.AlphaAnimation; 75b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.animation.Animation; 76b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.widget.ImageView; 77b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.widget.TextView; 78b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.widget.Toast; 79b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 80b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectpublic class VideoCamera extends Activity implements View.OnClickListener, 818d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project ShutterButton.OnShutterButtonListener, SurfaceHolder.Callback, MediaRecorder.OnErrorListener, MediaRecorder.OnInfoListener { 82b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 83b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final String TAG = "videocamera"; 84b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 85b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final boolean DEBUG = true; 86b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final boolean DEBUG_SUPPRESS_AUDIO_RECORDING = DEBUG && false; 87b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final boolean DEBUG_DO_NOT_REUSE_MEDIA_RECORDER = DEBUG && true; 88b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final boolean DEBUG_LOG_APP_LIFECYCLE = DEBUG && false; 89b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 90b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final int CLEAR_SCREEN_DELAY = 4; 91b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final int UPDATE_RECORD_TIME = 5; 92b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 93b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final int SCREEN_DELAY = 2 * 60 * 1000; 94b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 95b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final long NO_STORAGE_ERROR = -1L; 96b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final long CANNOT_STAT_ERROR = -2L; 97b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final long LOW_STORAGE_THRESHOLD = 512L * 1024L; 98e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project private static final long SHARE_FILE_LENGTH_LIMIT = 3L * 1024L * 1024L; 99b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1009a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project private static final int STORAGE_STATUS_OK = 0; 1019a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project private static final int STORAGE_STATUS_LOW = 1; 1029a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project private static final int STORAGE_STATUS_NONE = 2; 1039a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project 104b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public static final int MENU_SETTINGS = 6; 105b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public static final int MENU_GALLERY_PHOTOS = 7; 106b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public static final int MENU_GALLERY_VIDEOS = 8; 107b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public static final int MENU_SAVE_GALLERY_PHOTO = 34; 108b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public static final int MENU_SAVE_PLAY_VIDEO = 35; 109b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public static final int MENU_SAVE_SELECT_VIDEO = 36; 110b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public static final int MENU_SAVE_NEW_VIDEO = 37; 111b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 112b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project SharedPreferences mPreferences; 113b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 114b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final float VIDEO_ASPECT_RATIO = 176.0f / 144.0f; 115b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project VideoPreview mVideoPreview; 116b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project SurfaceHolder mSurfaceHolder = null; 117b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project ImageView mBlackout = null; 118b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project ImageView mVideoFrame; 119b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Bitmap mVideoFrameBitmap; 120de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project private TransitionDrawable mThumbnailTransition; 121de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project private Drawable[] mThumbnails; 122de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project private boolean mShouldTransitionThumbnails; 123de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project private ImageView mLastPictureButton; 124de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project private Bitmap mLastPictureThumb; 125b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1268d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project private static final int MAX_RECORDING_DURATION_MS = 10 * 60 * 1000; 1278d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project 1289a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project private int mStorageStatus = STORAGE_STATUS_OK; 1299a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project 130b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private MediaRecorder mMediaRecorder; 131b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private boolean mMediaRecorderRecording = false; 132b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private long mRecordingStartTime; 133b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // The video file that the hardware camera is about to record into 134b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // (or is recording into.) 135b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private String mCameraVideoFilename; 136b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private FileDescriptor mCameraVideoFileDescriptor; 137b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 138b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // The video file that has already been recorded, and that is being 139b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // examined by the user. 140b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private String mCurrentVideoFilename; 1418d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project private long mCurrentVideoFileLength = 0L; 142b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private Uri mCurrentVideoUri; 143b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private ContentValues mCurrentVideoValues; 144b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 145b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project boolean mPausing = false; 146b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 147b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project static ContentResolver mContentResolver; 148b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 149b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int mCurrentZoomIndex = 0; 150b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 151b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private ShutterButton mShutterButton; 152b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private TextView mRecordingTimeView; 1538d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project private boolean mRecordingTimeCountsDown = false; 154b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 155b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project ArrayList<MenuItem> mGalleryItems = new ArrayList<MenuItem>(); 156b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 157b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project View mPostPictureAlert; 158b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project LocationManager mLocationManager = null; 159b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 160b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private Handler mHandler = new MainHandler(); 161b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 162b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project /** This Handler is used to post message back onto the main thread of the application */ 163b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private class MainHandler extends Handler { 164b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 165b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void handleMessage(Message msg) { 166b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project switch (msg.what) { 167b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 168b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case CLEAR_SCREEN_DELAY: { 169b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project clearScreenOnFlag(); 170b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 171b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 172b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 173b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case UPDATE_RECORD_TIME: { 174b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mMediaRecorderRecording) { 175b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project long now = SystemClock.uptimeMillis(); 176b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project long delta = now - mRecordingStartTime; 1778d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project 1788d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project // Starting a minute before reaching the max duration 1798d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project // limit, we'll countdown the remaining time instead. 1808d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project boolean countdown_remaining_time = 1818d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project (delta >= MAX_RECORDING_DURATION_MS - 60000); 1828d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project 1838d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project if (countdown_remaining_time) { 1848d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project delta = Math.max(0, MAX_RECORDING_DURATION_MS - delta); 1858d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project } 1868d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project 1878d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project long seconds = (delta + 500) / 1000; // round to nearest 188b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project long minutes = seconds / 60; 189b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project long hours = minutes / 60; 190b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project long remainderMinutes = minutes - (hours * 60); 191b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project long remainderSeconds = seconds - (minutes * 60); 192b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 193b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String secondsString = Long.toString(remainderSeconds); 194b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (secondsString.length() < 2) { 195b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project secondsString = "0" + secondsString; 196b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 197b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String minutesString = Long.toString(remainderMinutes); 198b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (minutesString.length() < 2) { 199b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project minutesString = "0" + minutesString; 200b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 201b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String text = minutesString + ":" + secondsString; 202b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (hours > 0) { 203b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String hoursString = Long.toString(hours); 204b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (hoursString.length() < 2) { 205b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project hoursString = "0" + hoursString; 206b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 207b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project text = hoursString + ":" + text; 208b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 209b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mRecordingTimeView.setText(text); 2108d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project 2118d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project if (mRecordingTimeCountsDown != countdown_remaining_time) { 2128d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project // Avoid setting the color on every update, do it only 2138d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project // when it needs changing. 2148d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project 2158d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project mRecordingTimeCountsDown = countdown_remaining_time; 2168d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project 2178d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project int color = getResources().getColor( 2188d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project countdown_remaining_time ? R.color.recording_time_remaining_text 2198d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project : R.color.recording_time_elapsed_text); 2208d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project 2218d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project mRecordingTimeView.setTextColor(color); 2228d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project } 2238d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project 224b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // Work around a limitation of the T-Mobile G1: The T-Mobile 225b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // hardware blitter can't pixel-accurately scale and clip at the same time, 226b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // and the SurfaceFlinger doesn't attempt to work around this limitation. 227b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // In order to avoid visual corruption we must manually refresh the entire 228b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // surface view when changing any overlapping view's contents. 229b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mVideoPreview.invalidate(); 230b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mHandler.sendEmptyMessageDelayed(UPDATE_RECORD_TIME, 1000); 231b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 232b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 233b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 234b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 235b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project default: 236b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Unhandled message: " + msg.what); 237b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 238b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 239b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 240b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project }; 241b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 242b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 243b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 244b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void onReceive(Context context, Intent intent) { 245b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String action = intent.getAction(); 246b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (action.equals(Intent.ACTION_MEDIA_EJECT)) { 2479a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project updateAndShowStorageHint(false); 248b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project stopVideoRecording(); 249b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project initializeVideo(); 250b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else if (action.equals(Intent.ACTION_MEDIA_MOUNTED)) { 2519a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project updateAndShowStorageHint(true); 252b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project initializeVideo(); 253b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else if (action.equals(Intent.ACTION_MEDIA_UNMOUNTED)) { 254b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // SD card unavailable 2559a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project // handled in ACTION_MEDIA_EJECT 256b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else if (action.equals(Intent.ACTION_MEDIA_SCANNER_STARTED)) { 257b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Toast.makeText(VideoCamera.this, getResources().getString(R.string.wait), 5000); 258b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else if (action.equals(Intent.ACTION_MEDIA_SCANNER_FINISHED)) { 2599a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project updateAndShowStorageHint(true); 260b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 261b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 262b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project }; 263b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 264b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project static private String createName(long dateTaken) { 265b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return DateFormat.format("yyyy-MM-dd kk.mm.ss", dateTaken).toString(); 266b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 267b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 268b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project /** Called with the activity is first created. */ 269b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 270b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void onCreate(Bundle icicle) { 271b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (DEBUG_LOG_APP_LIFECYCLE) { 272b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "onCreate " + this.hashCode()); 273b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 274b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project super.onCreate(icicle); 275b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 276b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); 277b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 278b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mPreferences = PreferenceManager.getDefaultSharedPreferences(this); 279b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mContentResolver = getContentResolver(); 280b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 281b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project //setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT); 282b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project requestWindowFeature(Window.FEATURE_PROGRESS); 283b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setContentView(R.layout.video_camera); 284b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 285b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mVideoPreview = (VideoPreview) findViewById(R.id.camera_preview); 286b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mVideoPreview.setAspectRatio(VIDEO_ASPECT_RATIO); 287b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 288b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // don't set mSurfaceHolder here. We have it set ONLY within 289b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // surfaceCreated / surfaceDestroyed, other parts of the code 290b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // assume that when it is set, the surface is also set. 291b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project SurfaceHolder holder = mVideoPreview.getHolder(); 292b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project holder.addCallback(this); 293b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 294b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 295b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mBlackout = (ImageView) findViewById(R.id.blackout); 296b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mBlackout.setBackgroundDrawable(new ColorDrawable(0xFF000000)); 297b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 298b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mPostPictureAlert = findViewById(R.id.post_picture_panel); 299b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 300b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int[] ids = new int[]{R.id.play, R.id.share, R.id.discard, 301b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project R.id.cancel, R.id.attach}; 302b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project for (int id : ids) { 303b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project findViewById(id).setOnClickListener(this); 304b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 305b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 306b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mShutterButton = (ShutterButton) findViewById(R.id.shutter_button); 307b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mShutterButton.setOnShutterButtonListener(this); 308b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mRecordingTimeView = (TextView) findViewById(R.id.recording_time); 309b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mVideoFrame = (ImageView) findViewById(R.id.video_frame); 310de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mLastPictureButton = (ImageView) findViewById(R.id.last_picture_button); 311de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mLastPictureButton.setOnClickListener(this); 312b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 313b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 314e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project private void startShareVideoActivity() { 3158d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project if (mCurrentVideoFileLength > SHARE_FILE_LENGTH_LIMIT) { 316e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project Toast.makeText(VideoCamera.this, 317e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project R.string.too_large_to_attach, Toast.LENGTH_LONG).show(); 318e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project return; 319e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project } 320e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project Intent intent = new Intent(); 321e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project intent.setAction(Intent.ACTION_SEND); 322e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project intent.setType("video/3gpp"); 323e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project intent.putExtra(Intent.EXTRA_STREAM, mCurrentVideoUri); 324e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project try { 325e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project startActivity(Intent.createChooser(intent, getText(R.string.sendVideo))); 326e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project } catch (android.content.ActivityNotFoundException ex) { 327e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project Toast.makeText(VideoCamera.this, R.string.no_way_to_share_video, Toast.LENGTH_SHORT).show(); 328e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project } 329e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project } 330e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project 331b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void onClick(View v) { 332b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project switch (v.getId()) { 333b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 334b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case R.id.gallery: 335b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project MenuHelper.gotoCameraVideoGallery(this); 336b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 337b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 338b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case R.id.attach: 339b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project doReturnToCaller(true); 340b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 341b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 342b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case R.id.cancel: 343b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project doReturnToCaller(false); 344b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 345b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 346b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case R.id.discard: { 347b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project discardCurrentVideoAndStartPreview(); 348b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 349b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 350b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 351b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case R.id.share: { 352e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project startShareVideoActivity(); 353b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 354b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 355b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 356b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case R.id.play: { 357b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project doPlayCurrentVideo(); 358b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 359b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 360de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 361de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project case R.id.last_picture_button: { 362de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project stopPreviewAndShowAlert(); 363de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project break; 364de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 365b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 366b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 367b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 368b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void onShutterButtonFocus(ShutterButton button, boolean pressed) { 369de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project // Do nothing (everything happens in onShutterButtonClick). 370de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 371de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 372de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project public void onShutterButtonClick(ShutterButton button) { 373b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project switch (button.getId()) { 374b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case R.id.shutter_button: 375de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project if (mMediaRecorderRecording) { 376de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project if (isVideoCaptureIntent()) { 377de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project stopVideoRecordingAndShowAlert(); 378b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 379de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project stopVideoRecordingAndShowThumbnail(); 380de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project doStartCaptureMode(); 381b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 382de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } else if (mVideoFrame.getVisibility() == View.VISIBLE) { 383de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project doStartCaptureMode(); 384de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project startVideoRecording(); 385de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } else { 386de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project startVideoRecording(); 387b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 388b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 389b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 390b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 391b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 392b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void doStartCaptureMode() { 393b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (isVideoCaptureIntent()) { 394b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project discardCurrentVideoAndStartPreview(); 395b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 396b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project hideVideoFrameAndStartPreview(); 397b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 398b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 399b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 400b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void doPlayCurrentVideo() { 401b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.e(TAG, "Playing current video: " + mCurrentVideoUri); 402b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Intent intent = new Intent(Intent.ACTION_VIEW, mCurrentVideoUri); 403b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project try { 404b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project startActivity(intent); 405b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } catch (android.content.ActivityNotFoundException ex) { 406b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.e(TAG, "Couldn't view video " + mCurrentVideoUri, ex); 407b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 408b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 409b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 410b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void discardCurrentVideoAndStartPreview() { 411b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project deleteCurrentVideo(); 412b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project hideVideoFrameAndStartPreview(); 413b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 414b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 415b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private OnScreenHint mStorageHint; 416b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 4179a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project private void updateAndShowStorageHint(boolean mayHaveSd) { 4189a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project mStorageStatus = getStorageStatus(mayHaveSd); 4199a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project showStorageHint(); 4209a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project } 4219a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project 4229a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project private void showStorageHint() { 423b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String errorMessage = null; 4249a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project switch (mStorageStatus) { 4259a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project case STORAGE_STATUS_NONE: 426b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project errorMessage = getString(R.string.no_storage); 4279a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project break; 4289a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project case STORAGE_STATUS_LOW: 429b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project errorMessage = getString(R.string.spaceIsLow_content); 430b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 431b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (errorMessage != null) { 432b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mStorageHint == null) { 433b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mStorageHint = OnScreenHint.makeText(this, errorMessage); 434b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 435b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mStorageHint.setText(errorMessage); 436b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 437b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mStorageHint.show(); 438b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else if (mStorageHint != null) { 439b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mStorageHint.cancel(); 440b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mStorageHint = null; 441b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 442b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 443b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 4449a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project private int getStorageStatus(boolean mayHaveSd) { 4459a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project long remaining = mayHaveSd ? getAvailableStorage() : NO_STORAGE_ERROR; 4469a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project if (remaining == NO_STORAGE_ERROR) { 4479a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project return STORAGE_STATUS_NONE; 4489a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project } 4499a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project return remaining < LOW_STORAGE_THRESHOLD 4509a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project ? STORAGE_STATUS_LOW : STORAGE_STATUS_OK; 4519a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project } 4529a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project 453b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 454b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void onResume() { 455b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (DEBUG_LOG_APP_LIFECYCLE) { 456b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "onResume " + this.hashCode()); 457b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 458b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project super.onResume(); 459b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 460b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenTimeoutLong(); 461b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 462b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mPausing = false; 463b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 464b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // install an intent filter to receive SD card related events. 465b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MEDIA_MOUNTED); 466b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project intentFilter.addAction(Intent.ACTION_MEDIA_EJECT); 467b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project intentFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED); 468b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_STARTED); 469b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED); 470b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project intentFilter.addDataScheme("file"); 471b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project registerReceiver(mReceiver, intentFilter); 4729a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project mStorageStatus = getStorageStatus(true); 4739a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project 4749a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project mHandler.postDelayed(new Runnable() { 4759a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project public void run() { 4769a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project showStorageHint(); 4779a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project } 4789a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project }, 200); 479b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 480b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mBlackout.setVisibility(View.INVISIBLE); 481b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mVideoFrameBitmap == null) { 482b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project initializeVideo(); 483b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 484de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project showVideoFrame(); 485b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 486b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 487b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 488b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 489b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void onStop() { 490b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (DEBUG_LOG_APP_LIFECYCLE) { 491b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "onStop " + this.hashCode()); 492b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 493b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project stopVideoRecording(); 494b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenTimeoutSystemDefault(); 495b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project super.onStop(); 496b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 497b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 498b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 499b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project protected void onPause() { 500b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (DEBUG_LOG_APP_LIFECYCLE) { 501b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "onPause " + this.hashCode()); 502b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 503b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project super.onPause(); 504b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 505b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project stopVideoRecording(); 506de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project hideVideoFrame(); 507b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 508b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mPausing = true; 509b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 5109c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project unregisterReceiver(mReceiver); 511b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mBlackout.setVisibility(View.VISIBLE); 512b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenTimeoutSystemDefault(); 513b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 514b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mStorageHint != null) { 515b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mStorageHint.cancel(); 516b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mStorageHint = null; 517b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 518b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 519b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 520b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 521b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public boolean onKeyDown(int keyCode, KeyEvent event) { 522b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenTimeoutLong(); 523b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 524b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project switch (keyCode) { 525b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case KeyEvent.KEYCODE_BACK: 526b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mMediaRecorderRecording) { 527de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mShutterButton.performClick(); 528b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 529b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else if(isPostRecordingAlertVisible()) { 530b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project hideVideoFrameAndStartPreview(); 531b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 532b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 533b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 534b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case KeyEvent.KEYCODE_CAMERA: 535b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (event.getRepeatCount() == 0) { 536de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mShutterButton.performClick(); 537b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 538b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 539de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project break; 540b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case KeyEvent.KEYCODE_DPAD_CENTER: 541b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (event.getRepeatCount() == 0) { 542de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mShutterButton.performClick(); 543de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project return true; 544b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 545b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 546b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case KeyEvent.KEYCODE_MENU: 547b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mMediaRecorderRecording) { 548de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mShutterButton.performClick(); 549b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 550b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 551b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 552b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 553b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 554b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return super.onKeyDown(keyCode, event); 555b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 556b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 557b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 558b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public boolean onKeyUp(int keyCode, KeyEvent event) { 559b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project switch(keyCode) { 560b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case KeyEvent.KEYCODE_CAMERA: 561b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mShutterButton.setPressed(false); 562b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 563b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 564b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return super.onKeyUp(keyCode, event); 565b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 566b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 567b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 568b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project stopVideoRecording(); 569b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project initializeVideo(); 570b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 571b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 572b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void surfaceCreated(SurfaceHolder holder) { 573b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mSurfaceHolder = holder; 574b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 575b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 576b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void surfaceDestroyed(SurfaceHolder holder) { 577b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mSurfaceHolder = null; 578b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 579b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 580b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project void gotoGallery() { 581b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project MenuHelper.gotoCameraVideoGallery(this); 582b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 583b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 584b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 585b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public boolean onPrepareOptionsMenu(Menu menu) { 586b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project super.onPrepareOptionsMenu(menu); 587b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 588b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project for (int i = 1; i <= MenuHelper.MENU_ITEM_MAX; i++) { 589b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (i != MenuHelper.GENERIC_ITEM) { 590b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project menu.setGroupVisible(i, false); 591b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 592b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 593b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 594b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project menu.setGroupVisible(MenuHelper.VIDEO_MODE_ITEM, true); 595b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 596b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 597b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 598b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 599b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public boolean onCreateOptionsMenu(Menu menu) { 600b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project super.onCreateOptionsMenu(menu); 601b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 602b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (isVideoCaptureIntent()) { 603b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // No options menu for attach mode. 604b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return false; 605b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 606b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project addBaseMenuItems(menu); 607b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project MenuHelper.addImageMenuItems( 608b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project menu, 609b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project MenuHelper.INCLUDE_ALL & ~MenuHelper.INCLUDE_ROTATE_MENU, 610b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project false, 611b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project VideoCamera.this, 612b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mHandler, 613b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 614b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // Handler for deletion 615b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project new Runnable() { 616b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void run() { 617b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // What do we do here? 618b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // mContentResolver.delete(uri, null, null); 619b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 620b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project }, 621b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project new MenuHelper.MenuInvoker() { 622b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void run(final MenuHelper.MenuCallback cb) { 623b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 624b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project }); 625b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 626b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project MenuItem gallery = menu.add(MenuHelper.IMAGE_SAVING_ITEM, MENU_SAVE_GALLERY_PHOTO, 0, 627b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project R.string.camera_gallery_photos_text).setOnMenuItemClickListener( 628b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project new MenuItem.OnMenuItemClickListener() { 629b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public boolean onMenuItemClick(MenuItem item) { 630b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project gotoGallery(); 631b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 632b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 633b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project }); 634b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project gallery.setIcon(android.R.drawable.ic_menu_gallery); 635b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 636b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 637b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 638b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 639b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private boolean isVideoCaptureIntent() { 640b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String action = getIntent().getAction(); 641b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return (MediaStore.ACTION_VIDEO_CAPTURE.equals(action)); 642b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 643b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 644b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void doReturnToCaller(boolean success) { 645b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Intent resultIntent = new Intent(); 646b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int resultCode; 647b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (success) { 648b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project resultCode = RESULT_OK; 649b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project resultIntent.setData(mCurrentVideoUri); 650b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 651b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project resultCode = RESULT_CANCELED; 652b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 653b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setResult(resultCode, resultIntent); 654b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project finish(); 655b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 656b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 657b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project /** 658b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * Returns 659b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * @return number of bytes available, or an ERROR code. 660b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project */ 661b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static long getAvailableStorage() { 662b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project try { 663b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (!ImageManager.hasStorage()) { 664b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return NO_STORAGE_ERROR; 665b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 666b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String storageDirectory = Environment.getExternalStorageDirectory().toString(); 667b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project StatFs stat = new StatFs(storageDirectory); 668b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return ((long)stat.getAvailableBlocks() * (long)stat.getBlockSize()); 669b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 670b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } catch (Exception ex) { 671b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // if we can't stat the filesystem then we don't know how many 672b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // free bytes exist. It might be zero but just leave it 673b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // blank since we really don't know. 674b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return CANNOT_STAT_ERROR; 675b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 676b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 677b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 678b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void cleanupEmptyFile() { 679b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mCameraVideoFilename != null) { 680b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project File f = new File(mCameraVideoFilename); 681b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (f.length() == 0 && f.delete()) { 682b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Empty video file deleted: " + mCameraVideoFilename); 683b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCameraVideoFilename = null; 684b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 685b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 686b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 687b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 688b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // Returns false if initializeVideo fails 689b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private boolean initializeVideo() { 690b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "initializeVideo"); 691b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project boolean isCaptureIntent = isVideoCaptureIntent(); 692b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Intent intent = getIntent(); 693b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Bundle myExtras = intent.getExtras(); 694b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 695b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (isCaptureIntent && myExtras != null) { 696b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Uri saveUri = (Uri) myExtras.getParcelable(MediaStore.EXTRA_OUTPUT); 697b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (saveUri != null) { 698b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project try { 699b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCameraVideoFileDescriptor = mContentResolver. 700b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project openFileDescriptor(saveUri, "rw").getFileDescriptor(); 701b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoUri = saveUri; 702b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 703b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project catch (java.io.FileNotFoundException ex) { 704b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // invalid uri 705b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.e(TAG, ex.toString()); 706b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 707b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 708b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 709b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project releaseMediaRecorder(); 710b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 711b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mSurfaceHolder == null) { 712b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "SurfaceHolder is null"); 713b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return false; 714b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 715b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 716b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder = new MediaRecorder(); 717b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 718b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (DEBUG_SUPPRESS_AUDIO_RECORDING) { 719b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "DEBUG_SUPPRESS_AUDIO_RECORDING is true."); 720b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 721b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); 722b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 723b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); 724b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); 725b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 7268d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project mMediaRecorder.setMaxDuration(MAX_RECORDING_DURATION_MS); 7278d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project 7289a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project if (mStorageStatus != STORAGE_STATUS_OK) { 729b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setOutputFile("/dev/null"); 730b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 731b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // We try Uri in intent first. If it doesn't work, use our own instead. 732b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mCameraVideoFileDescriptor != null) { 733b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setOutputFile(mCameraVideoFileDescriptor); 734b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 735b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project createVideoPath(); 736b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setOutputFile(mCameraVideoFilename); 737b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 738b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 739b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 740b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project boolean videoQualityHigh = getBooleanPreference(CameraSettings.KEY_VIDEO_QUALITY, 741b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project CameraSettings.DEFAULT_VIDEO_QUALITY_VALUE); 742b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 743b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (intent.hasExtra(MediaStore.EXTRA_VIDEO_QUALITY)) { 744b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int extraVideoQuality = intent.getIntExtra(MediaStore.EXTRA_VIDEO_QUALITY, 0); 745b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project videoQualityHigh = (extraVideoQuality > 0); 746b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 747b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 748b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // Use the same frame rate for both, since internally 749b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // if the frame rate is too large, it can cause camera to become 750b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // unstable. We need to fix the MediaRecorder to disable the support 751b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // of setting frame rate for now. 752b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setVideoFrameRate(20); 753b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (videoQualityHigh) { 754b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setVideoSize(352,288); 755b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 756b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setVideoSize(176,144); 757b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 758b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263); 759b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (!DEBUG_SUPPRESS_AUDIO_RECORDING) { 760b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); 761b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 762b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface()); 763de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 764de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project long remaining = getAvailableStorage(); 765de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project // remaining >= LOW_STORAGE_THRESHOLD at this point, reserve a quarter 766de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project // of that to make it more likely that recording can complete successfully. 767de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project try { 768de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mMediaRecorder.setMaxFileSize(remaining - LOW_STORAGE_THRESHOLD / 4); 769de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } catch (RuntimeException exception) { 770de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project // We are going to ignore failure of setMaxFileSize here, as 771de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project // a) The composer selected may simply not support it, or 772de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project // b) The underlying media framework may not handle 64-bit range 773de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project // on the size restriction. 774de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 775de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 776b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project try { 777b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.prepare(); 778b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } catch (IOException exception) { 779b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.e(TAG, "prepare failed for " + mCameraVideoFilename); 780b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project releaseMediaRecorder(); 781b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // TODO: add more exception handling logic here 782b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return false; 783b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 784b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorderRecording = false; 785b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 786b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 787b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 788b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void releaseMediaRecorder() { 789b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Releasing media recorder."); 790b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mMediaRecorder != null) { 791b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project cleanupEmptyFile(); 792b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.reset(); 793b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.release(); 794b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder = null; 795b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 796b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 797b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 798b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void restartPreview() { 799b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (DEBUG_DO_NOT_REUSE_MEDIA_RECORDER) { 800b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "DEBUG_DO_NOT_REUSE_MEDIA_RECORDER recreating mMediaRecorder."); 801b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project initializeVideo(); 802b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 803b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project try { 804b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.prepare(); 805b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } catch (IOException exception) { 806b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.e(TAG, "prepare failed for " + mCameraVideoFilename); 807b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project releaseMediaRecorder(); 808b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // TODO: add more exception handling logic here 809b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 810b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 811de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project if (mShouldTransitionThumbnails) { 812de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mShouldTransitionThumbnails = false; 813de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mThumbnailTransition.startTransition(500); 814de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 815b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 816b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 817b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private int getIntPreference(String key, int defaultValue) { 818b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String s = mPreferences.getString(key, ""); 819b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int result = defaultValue; 820b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project try { 821b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project result = Integer.parseInt(s); 822b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } catch (NumberFormatException e) { 823b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // Ignore, result is already the default value. 824b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 825b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return result; 826b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 827b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 828b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private boolean getBooleanPreference(String key, boolean defaultValue) { 829b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return getIntPreference(key, defaultValue ? 1 : 0) != 0; 830b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 831b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 832b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void createVideoPath() { 833b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project long dateTaken = System.currentTimeMillis(); 834b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String title = createName(dateTaken); 835b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String displayName = title + ".3gp"; // Used when emailing. 836b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String cameraDirPath = ImageManager.CAMERA_IMAGE_BUCKET_NAME; 837b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project File cameraDir = new File(cameraDirPath); 838b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project cameraDir.mkdirs(); 839b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project SimpleDateFormat dateFormat = new SimpleDateFormat( 840b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project getString(R.string.video_file_name_format)); 841b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Date date = new Date(dateTaken); 842b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String filepart = dateFormat.format(date); 843b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String filename = cameraDirPath + "/" + filepart + ".3gp"; 844b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project ContentValues values = new ContentValues(7); 845b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project values.put(Video.Media.TITLE, title); 846b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project values.put(Video.Media.DISPLAY_NAME, displayName); 847b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project values.put(Video.Media.DESCRIPTION, ""); 848b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project values.put(Video.Media.DATE_TAKEN, dateTaken); 849b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project values.put(Video.Media.MIME_TYPE, "video/3gpp"); 850b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project values.put(Video.Media.DATA, filename); 851b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCameraVideoFilename = filename; 852b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Current camera video filename: " + mCameraVideoFilename); 853b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoValues = values; 854b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 855b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 856b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void registerVideo() { 857b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mCameraVideoFileDescriptor == null) { 858b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Uri videoTable = Uri.parse("content://media/external/video/media"); 859b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoUri = mContentResolver.insert(videoTable, 860b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoValues); 861b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Current video URI: " + mCurrentVideoUri); 862b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 863b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoValues = null; 864b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 865b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 866b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void deleteCurrentVideo() { 867b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mCurrentVideoFilename != null) { 868b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project deleteVideoFile(mCurrentVideoFilename); 869b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoFilename = null; 870b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 871b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mCurrentVideoUri != null) { 872b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mContentResolver.delete(mCurrentVideoUri, null, null); 873b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoUri = null; 874b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 875de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project updateAndShowStorageHint(true); 876b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 877b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 878b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void deleteVideoFile(String fileName) { 879b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Deleting video " + fileName); 880b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project File f = new File(fileName); 881b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (! f.delete()) { 882b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Could not delete " + fileName); 883b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 884b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 885b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 886b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void addBaseMenuItems(Menu menu) { 887b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project MenuHelper.addSwitchModeMenuItem(menu, this, false); 888b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project { 889b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project MenuItem gallery = menu.add(MenuHelper.IMAGE_MODE_ITEM, MENU_GALLERY_PHOTOS, 0, R.string.camera_gallery_photos_text).setOnMenuItemClickListener(new OnMenuItemClickListener() { 890b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public boolean onMenuItemClick(MenuItem item) { 891b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project gotoGallery(); 892b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 893b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 894b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project }); 895b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project gallery.setIcon(android.R.drawable.ic_menu_gallery); 896b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mGalleryItems.add(gallery); 897b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 898b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project { 899b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project MenuItem gallery = menu.add(MenuHelper.VIDEO_MODE_ITEM, MENU_GALLERY_VIDEOS, 0, R.string.camera_gallery_photos_text).setOnMenuItemClickListener(new OnMenuItemClickListener() { 900b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public boolean onMenuItemClick(MenuItem item) { 901b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project gotoGallery(); 902b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 903b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 904b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project }); 905b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project gallery.setIcon(android.R.drawable.ic_menu_gallery); 906b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mGalleryItems.add(gallery); 907b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 908b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 909b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project MenuItem item = menu.add(MenuHelper.GENERIC_ITEM, MENU_SETTINGS, 0, R.string.settings).setOnMenuItemClickListener(new OnMenuItemClickListener() { 910b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public boolean onMenuItemClick(MenuItem item) { 911b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Intent intent = new Intent(); 912b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project intent.setClass(VideoCamera.this, CameraSettings.class); 913b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project startActivity(intent); 914b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 915b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 916b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project }); 917b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project item.setIcon(android.R.drawable.ic_menu_preferences); 918b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 919b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 920b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // from MediaRecorder.OnErrorListener 921b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void onError(MediaRecorder mr, int what, int extra) { 922b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (what == MediaRecorder.MEDIA_RECORDER_ERROR_UNKNOWN) { 923b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // We may have run out of space on the sdcard. 924b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project stopVideoRecording(); 9259a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project updateAndShowStorageHint(true); 926b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 927b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 928b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 9298d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project // from MediaRecorder.OnInfoListener 9308d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project public void onInfo(MediaRecorder mr, int what, int extra) { 9318d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) { 932de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mShutterButton.performClick(); 933de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } else if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED) { 934de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mShutterButton.performClick(); 935de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project updateAndShowStorageHint(true); 9368d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project } 9378d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project } 9388d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project 9399c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project /* 9409c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project * Make sure we're not recording music playing in the background, ask 9419c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project * the MediaPlaybackService to pause playback. 9429c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project */ 9439c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project private void pauseAudioPlayback() { 9449c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project // Shamelessly copied from MediaPlaybackService.java, which 9459c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project // should be public, but isn't. 9469c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project Intent i = new Intent("com.android.music.musicservicecommand"); 9479c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project i.putExtra("command", "pause"); 9489c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project 9499c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project sendBroadcast(i); 9509c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project } 9519c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project 952b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void startVideoRecording() { 953b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "startVideoRecording"); 954b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (!mMediaRecorderRecording) { 955b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 9569a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project if (mStorageStatus != STORAGE_STATUS_OK) { 957b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Storage issue, ignore the start request"); 958b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return; 959b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 960b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 961b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // Check mMediaRecorder to see whether it is initialized or not. 962b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mMediaRecorder == null && initializeVideo() == false ) { 963b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.e(TAG, "Initialize video (MediaRecorder) failed."); 964b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return; 965b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 966b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 9679c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project pauseAudioPlayback(); 9689c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project 969b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project try { 970b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setOnErrorListener(this); 9718d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project mMediaRecorder.setOnInfoListener(this); 972b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.start(); // Recording is now started 973b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } catch (RuntimeException e) { 974b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.e(TAG, "Could not start media recorder. ", e); 975b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return; 976b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 977b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorderRecording = true; 978b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mRecordingStartTime = SystemClock.uptimeMillis(); 979b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project updateRecordingIndicator(true); 980b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mRecordingTimeView.setText(""); 981b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mRecordingTimeView.setVisibility(View.VISIBLE); 982b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mHandler.sendEmptyMessage(UPDATE_RECORD_TIME); 983b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenTimeoutInfinite(); 984de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project hideLastPictureButton(); 985de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project recycleVideoFrameBitmap(); 986b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 987b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 988b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 989b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void updateRecordingIndicator(boolean showRecording) { 990b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int drawableId = showRecording ? R.drawable.ic_camera_bar_indicator_record 991b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project : R.drawable.ic_camera_indicator_video; 992b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Drawable drawable = getResources().getDrawable(drawableId); 993b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mShutterButton.setImageDrawable(drawable); 994b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 995b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 996de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project private void stopVideoRecordingAndShowThumbnail() { 997de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project Log.v(TAG, "stopVideoRecordingAndShowThumbnail"); 998b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mMediaRecorderRecording) { 999b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project stopVideoRecording(); 1000de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project acquireVideoFrame(); 1001de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project setLastPictureThumb(mVideoFrameBitmap); 1002de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project showLastPictureButton(); 1003b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1004b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1005b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1006de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project private void stopVideoRecordingAndShowAlert() { 1007de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project Log.v(TAG, "stopVideoRecordingAndShowAlert"); 1008de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project if (mMediaRecorderRecording) { 1009de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project stopVideoRecording(); 1010de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project acquireVideoFrame(); 1011de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project showVideoFrame(); 1012de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 1013de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 1014de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 1015de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project private void stopPreviewAndShowAlert() { 1016de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project stopVideoRecording(); 1017de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project showVideoFrame(); 1018de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 1019de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 1020de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project private void showVideoFrame() { 1021b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int[] pickIds = {R.id.attach, R.id.cancel}; 1022b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int[] normalIds = {R.id.gallery, R.id.share, R.id.discard}; 1023b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int[] alwaysOnIds = {R.id.play}; 1024b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int[] hideIds = pickIds; 1025b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int[] connectIds = normalIds; 1026b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (isVideoCaptureIntent()) { 1027b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project hideIds = normalIds; 1028b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project connectIds = pickIds; 1029b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1030b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project for(int id : hideIds) { 1031b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mPostPictureAlert.findViewById(id).setVisibility(View.GONE); 1032b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 10338d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project ActionMenuButton shareButton = 10348d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project (ActionMenuButton) mPostPictureAlert.findViewById(R.id.share); 10358d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project shareButton.setRestricted( 10368d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project mCurrentVideoFileLength > SHARE_FILE_LENGTH_LIMIT); 1037b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project connectAndFadeIn(connectIds); 1038b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project connectAndFadeIn(alwaysOnIds); 1039de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project hideLastPictureButton(); 1040de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mVideoFrame.setVisibility(View.VISIBLE); 1041b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mPostPictureAlert.setVisibility(View.VISIBLE); 1042b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1043b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1044de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project private void hideVideoFrame() { 1045de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mVideoFrame.setVisibility(View.INVISIBLE); 1046de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mPostPictureAlert.setVisibility(View.INVISIBLE); 1047de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project showLastPictureButton(); 1048de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 1049de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 1050b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void connectAndFadeIn(int[] connectIds) { 1051b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project for(int id : connectIds) { 1052b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project View view = mPostPictureAlert.findViewById(id); 1053b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project view.setOnClickListener(this); 1054b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Animation animation = new AlphaAnimation(0F, 1F); 1055b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project animation.setDuration(500); 1056b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project view.setAnimation(animation); 1057b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1058b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1059b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1060b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private boolean isPostRecordingAlertVisible() { 1061b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return mPostPictureAlert.getVisibility() == View.VISIBLE; 1062b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1063b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1064b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void stopVideoRecording() { 1065b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "stopVideoRecording"); 1066b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project boolean needToRegisterRecording = false; 1067b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mMediaRecorderRecording || mMediaRecorder != null) { 1068b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mMediaRecorderRecording && mMediaRecorder != null) { 1069b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project try { 1070b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setOnErrorListener(null); 10718d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project mMediaRecorder.setOnInfoListener(null); 1072b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.stop(); 1073b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } catch (RuntimeException e) { 1074b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.e(TAG, "stop fail: " + e.getMessage()); 1075b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 10768d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project 1077b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoFilename = mCameraVideoFilename; 10788d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project try { 10798d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project mCurrentVideoFileLength = new File(mCurrentVideoFilename).length(); 10808d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project } catch (RuntimeException e) { 10818d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project Log.e(TAG, "get file length fail: " + e.getMessage()); 10828d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project mCurrentVideoFileLength = 0; 10838d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project } 1084b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Setting current video filename: " + mCurrentVideoFilename); 1085b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project needToRegisterRecording = true; 1086b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorderRecording = false; 1087b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1088b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project releaseMediaRecorder(); 1089b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project updateRecordingIndicator(false); 1090b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mRecordingTimeView.setVisibility(View.GONE); 1091b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenTimeoutLong(); 1092b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 10939a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project if (needToRegisterRecording && mStorageStatus == STORAGE_STATUS_OK) { 10949a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project registerVideo(); 10959a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project } 1096b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1097b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCameraVideoFilename = null; 1098b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCameraVideoFileDescriptor = null; 1099b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1100b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1101b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void setScreenTimeoutSystemDefault() { 1102b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mHandler.removeMessages(CLEAR_SCREEN_DELAY); 1103b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project clearScreenOnFlag(); 1104b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1105b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1106b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void setScreenTimeoutLong() { 1107b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mHandler.removeMessages(CLEAR_SCREEN_DELAY); 1108b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenOnFlag(); 1109b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mHandler.sendEmptyMessageDelayed(CLEAR_SCREEN_DELAY, SCREEN_DELAY); 1110b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1111b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1112b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void setScreenTimeoutInfinite() { 1113b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mHandler.removeMessages(CLEAR_SCREEN_DELAY); 1114b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenOnFlag(); 1115b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1116b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1117b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void clearScreenOnFlag() { 1118b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Window w = getWindow(); 1119b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project final int keepScreenOnFlag = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; 1120b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if ((w.getAttributes().flags & keepScreenOnFlag) != 0) { 1121b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project w.clearFlags(keepScreenOnFlag); 1122b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1123b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1124b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1125b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void setScreenOnFlag() { 1126b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Window w = getWindow(); 1127b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project final int keepScreenOnFlag = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; 1128b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if ((w.getAttributes().flags & keepScreenOnFlag) == 0) { 1129b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project w.addFlags(keepScreenOnFlag); 1130b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1131b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1132b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1133b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void hideVideoFrameAndStartPreview() { 1134b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project hideVideoFrame(); 1135b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project restartPreview(); 1136b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1137b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1138de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project private void acquireVideoFrame() { 1139b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project recycleVideoFrameBitmap(); 1140b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mVideoFrameBitmap = ImageManager.createVideoThumbnail(mCurrentVideoFilename); 1141b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mVideoFrame.setImageBitmap(mVideoFrameBitmap); 1142de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project Log.v(TAG, "acquireVideoFrame:" + mVideoFrameBitmap); 1143b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1144b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1145de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project //TODO: Refactor the code so that the following code is shared between 1146de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project // VideoCamera.java and Camera.java 1147de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project private static Bitmap makeRoundedCorner(Bitmap thumb, int rx, int ry) { 1148de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project if (thumb == null) return null; 1149de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project int width = thumb.getWidth(); 1150de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project int height = thumb.getHeight(); 1151de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 1152de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 1153de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project Canvas canvas = new Canvas(result); 1154de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); 1155de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project paint.setStyle(Paint.Style.FILL); 1156de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project canvas.drawRoundRect(new RectF(0, 0, width, height), rx, ry, paint); 1157de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); 1158de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project canvas.drawBitmap(thumb, 0, 0, paint); 1159de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project return result; 1160de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 1161de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 1162de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project private void setLastPictureThumb(Bitmap videoFrame) { 1163de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 1164de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project final int PADDING_WIDTH = 6; 1165de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project final int PADDING_HEIGHT = 6; 1166de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project LayoutParams layoutParams = mLastPictureButton.getLayoutParams(); 1167de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project // Make the mini-thumbnail size smaller than the button size so that the image corners 1168de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project // don't peek out from the rounded corners of the frame_thumbnail graphic: 1169de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project final int miniThumbWidth = layoutParams.width - 2 * PADDING_WIDTH; 1170de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project final int miniThumbHeight = layoutParams.height - 2 * PADDING_HEIGHT; 1171de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 1172de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project Bitmap lastPictureThumb = ImageManager.extractMiniThumb(videoFrame, 1173de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project miniThumbWidth, miniThumbHeight, false); 1174de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project lastPictureThumb = makeRoundedCorner(lastPictureThumb, 3, 3); 1175de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 1176de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project Drawable[] vignetteLayers = new Drawable[2]; 1177de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project vignetteLayers[0] = getResources().getDrawable(R.drawable.frame_thumbnail); 1178de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project if (mThumbnails == null) { 1179de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mThumbnails = new Drawable[2]; 1180de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mThumbnails[1] = new BitmapDrawable(lastPictureThumb); 1181de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project vignetteLayers[1] = mThumbnails[1]; 1182de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } else { 1183de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mThumbnails[0] = mThumbnails[1]; 1184de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mThumbnails[1] = new BitmapDrawable(lastPictureThumb); 1185de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mThumbnailTransition = new TransitionDrawable(mThumbnails); 1186de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mShouldTransitionThumbnails = true; 1187de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project vignetteLayers[1] = mThumbnailTransition; 1188de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 1189de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 1190de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project LayerDrawable vignette = new LayerDrawable(vignetteLayers); 1191de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project vignette.setLayerInset(1, PADDING_WIDTH, PADDING_HEIGHT, 1192de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project PADDING_WIDTH, PADDING_HEIGHT); 1193de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mLastPictureButton.setImageDrawable(vignette); 1194de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 1195de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 1196de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project private void showLastPictureButton() { 1197de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mLastPictureButton.setVisibility(View.VISIBLE); 1198de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 1199de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 1200de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project private void hideLastPictureButton() { 1201de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mLastPictureButton.setVisibility(View.INVISIBLE); 1202b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1203b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1204b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void recycleVideoFrameBitmap() { 1205b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mVideoFrameBitmap != null) { 1206b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mVideoFrame.setImageDrawable(null); 1207b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mVideoFrameBitmap.recycle(); 1208b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mVideoFrameBitmap = null; 1209b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1210b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1211b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project} 1212