VideoCamera.java revision 095afa19556bf550262e3cccb9edacc04e6f726a
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.text.SimpleDateFormat; 23b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport java.util.ArrayList; 24b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport java.util.Date; 25b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 26b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.app.Activity; 27b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.BroadcastReceiver; 28b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.ContentResolver; 29b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.ContentValues; 30b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.Context; 31b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.Intent; 32b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.IntentFilter; 33b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.SharedPreferences; 34095afa19556bf550262e3cccb9edacc04e6f726aOwen Linimport android.database.Cursor; 35b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.graphics.Bitmap; 36b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.graphics.drawable.Drawable; 37b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.location.LocationManager; 38b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.media.MediaRecorder; 39b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.net.Uri; 40b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.Bundle; 41b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.Environment; 42b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.Handler; 43b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.Message; 44b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.StatFs; 45b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.SystemClock; 46b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.preference.PreferenceManager; 47b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.provider.MediaStore; 48b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.provider.MediaStore.Video; 49b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.text.format.DateFormat; 50b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.util.Log; 51b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.KeyEvent; 52b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.Menu; 53b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.MenuItem; 54b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.SurfaceHolder; 55b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.View; 56b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.Window; 57b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.WindowManager; 58b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.MenuItem.OnMenuItemClickListener; 59b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.animation.AlphaAnimation; 60b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.animation.Animation; 61b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.widget.ImageView; 62b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.widget.TextView; 63b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.widget.Toast; 64b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 65b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectpublic class VideoCamera extends Activity implements View.OnClickListener, 668d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project ShutterButton.OnShutterButtonListener, SurfaceHolder.Callback, MediaRecorder.OnErrorListener, MediaRecorder.OnInfoListener { 67b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 68b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final String TAG = "videocamera"; 69b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 70b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final boolean DEBUG = true; 71b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final boolean DEBUG_SUPPRESS_AUDIO_RECORDING = DEBUG && false; 72b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 73b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final int CLEAR_SCREEN_DELAY = 4; 74b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final int UPDATE_RECORD_TIME = 5; 75b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 76b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final int SCREEN_DELAY = 2 * 60 * 1000; 77b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 78b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final long NO_STORAGE_ERROR = -1L; 79b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final long CANNOT_STAT_ERROR = -2L; 80b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final long LOW_STORAGE_THRESHOLD = 512L * 1024L; 81e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project private static final long SHARE_FILE_LENGTH_LIMIT = 3L * 1024L * 1024L; 82b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 839a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project private static final int STORAGE_STATUS_OK = 0; 849a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project private static final int STORAGE_STATUS_LOW = 1; 859a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project private static final int STORAGE_STATUS_NONE = 2; 869a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project 87b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public static final int MENU_SETTINGS = 6; 88b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public static final int MENU_GALLERY_PHOTOS = 7; 89b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public static final int MENU_GALLERY_VIDEOS = 8; 90b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public static final int MENU_SAVE_GALLERY_PHOTO = 34; 91b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public static final int MENU_SAVE_PLAY_VIDEO = 35; 92b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public static final int MENU_SAVE_SELECT_VIDEO = 36; 93b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public static final int MENU_SAVE_NEW_VIDEO = 37; 94b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 95b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project SharedPreferences mPreferences; 96b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 97b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final float VIDEO_ASPECT_RATIO = 176.0f / 144.0f; 98b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project VideoPreview mVideoPreview; 99b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project SurfaceHolder mSurfaceHolder = null; 100b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project ImageView mVideoFrame; 1019bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 1029bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private boolean mIsVideoCaptureIntent; 1039bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // mLastPictureButton and mThumbController 1049bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // are non-null only if isVideoCaptureIntent() is true; 105de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project private ImageView mLastPictureButton; 1069bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private ThumbnailController mThumbController; 107b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1088d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project private static final int MAX_RECORDING_DURATION_MS = 10 * 60 * 1000; 1098d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project 1109a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project private int mStorageStatus = STORAGE_STATUS_OK; 1119a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project 112b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private MediaRecorder mMediaRecorder; 113b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private boolean mMediaRecorderRecording = false; 114b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private long mRecordingStartTime; 115b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // The video file that the hardware camera is about to record into 116b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // (or is recording into.) 117b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private String mCameraVideoFilename; 118b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private FileDescriptor mCameraVideoFileDescriptor; 119b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 120b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // The video file that has already been recorded, and that is being 121b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // examined by the user. 122b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private String mCurrentVideoFilename; 1238d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project private long mCurrentVideoFileLength = 0L; 124b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private Uri mCurrentVideoUri; 125b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private ContentValues mCurrentVideoValues; 126b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 127b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project boolean mPausing = false; 128b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 129b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project static ContentResolver mContentResolver; 130b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 131b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int mCurrentZoomIndex = 0; 132b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 133b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private ShutterButton mShutterButton; 134b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private TextView mRecordingTimeView; 1358d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project private boolean mRecordingTimeCountsDown = false; 136b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 137b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project ArrayList<MenuItem> mGalleryItems = new ArrayList<MenuItem>(); 138b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 139b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project View mPostPictureAlert; 140b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project LocationManager mLocationManager = null; 141b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 142b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private Handler mHandler = new MainHandler(); 143b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 144b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project /** This Handler is used to post message back onto the main thread of the application */ 145b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private class MainHandler extends Handler { 146b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 147b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void handleMessage(Message msg) { 148b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project switch (msg.what) { 149b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 150b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case CLEAR_SCREEN_DELAY: { 151b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project clearScreenOnFlag(); 152b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 153b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 154b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 155b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case UPDATE_RECORD_TIME: { 156b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mMediaRecorderRecording) { 157b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project long now = SystemClock.uptimeMillis(); 158b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project long delta = now - mRecordingStartTime; 1598d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project 1608d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project // Starting a minute before reaching the max duration 1618d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project // limit, we'll countdown the remaining time instead. 1628d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project boolean countdown_remaining_time = 1638d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project (delta >= MAX_RECORDING_DURATION_MS - 60000); 1648d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project 1658d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project if (countdown_remaining_time) { 1668d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project delta = Math.max(0, MAX_RECORDING_DURATION_MS - delta); 1678d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project } 1688d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project 1698d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project long seconds = (delta + 500) / 1000; // round to nearest 170b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project long minutes = seconds / 60; 171b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project long hours = minutes / 60; 172b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project long remainderMinutes = minutes - (hours * 60); 173b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project long remainderSeconds = seconds - (minutes * 60); 174b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 175b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String secondsString = Long.toString(remainderSeconds); 176b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (secondsString.length() < 2) { 177b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project secondsString = "0" + secondsString; 178b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 179b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String minutesString = Long.toString(remainderMinutes); 180b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (minutesString.length() < 2) { 181b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project minutesString = "0" + minutesString; 182b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 183b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String text = minutesString + ":" + secondsString; 184b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (hours > 0) { 185b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String hoursString = Long.toString(hours); 186b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (hoursString.length() < 2) { 187b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project hoursString = "0" + hoursString; 188b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 189b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project text = hoursString + ":" + text; 190b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 191b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mRecordingTimeView.setText(text); 1928d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project 1938d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project if (mRecordingTimeCountsDown != countdown_remaining_time) { 1948d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project // Avoid setting the color on every update, do it only 1958d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project // when it needs changing. 1968d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project 1978d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project mRecordingTimeCountsDown = countdown_remaining_time; 1988d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project 1998d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project int color = getResources().getColor( 2008d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project countdown_remaining_time ? R.color.recording_time_remaining_text 2018d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project : R.color.recording_time_elapsed_text); 2028d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project 2038d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project mRecordingTimeView.setTextColor(color); 2048d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project } 2058d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project 206b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // Work around a limitation of the T-Mobile G1: The T-Mobile 207b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // hardware blitter can't pixel-accurately scale and clip at the same time, 208b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // and the SurfaceFlinger doesn't attempt to work around this limitation. 209b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // In order to avoid visual corruption we must manually refresh the entire 210b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // surface view when changing any overlapping view's contents. 211b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mVideoPreview.invalidate(); 212b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mHandler.sendEmptyMessageDelayed(UPDATE_RECORD_TIME, 1000); 213b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 214b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 215b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 216b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 217b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project default: 218b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Unhandled message: " + msg.what); 219b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 220b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 221b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 222b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project }; 223b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 224b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 225b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 226b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void onReceive(Context context, Intent intent) { 227b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String action = intent.getAction(); 228b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (action.equals(Intent.ACTION_MEDIA_EJECT)) { 2299a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project updateAndShowStorageHint(false); 230b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project stopVideoRecording(); 231b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project initializeVideo(); 232b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else if (action.equals(Intent.ACTION_MEDIA_MOUNTED)) { 2339a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project updateAndShowStorageHint(true); 234b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project initializeVideo(); 235b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else if (action.equals(Intent.ACTION_MEDIA_UNMOUNTED)) { 236b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // SD card unavailable 2379a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project // handled in ACTION_MEDIA_EJECT 238b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else if (action.equals(Intent.ACTION_MEDIA_SCANNER_STARTED)) { 239b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Toast.makeText(VideoCamera.this, getResources().getString(R.string.wait), 5000); 240b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else if (action.equals(Intent.ACTION_MEDIA_SCANNER_FINISHED)) { 2419a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project updateAndShowStorageHint(true); 242b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 243b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 244b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project }; 245b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 246b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project static private String createName(long dateTaken) { 247b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return DateFormat.format("yyyy-MM-dd kk.mm.ss", dateTaken).toString(); 248b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 249b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 250b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project /** Called with the activity is first created. */ 251b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 252b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void onCreate(Bundle icicle) { 253b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project super.onCreate(icicle); 254b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 255b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); 256b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 257b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mPreferences = PreferenceManager.getDefaultSharedPreferences(this); 258b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mContentResolver = getContentResolver(); 259b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 260b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project //setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT); 261b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project requestWindowFeature(Window.FEATURE_PROGRESS); 262b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setContentView(R.layout.video_camera); 263b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 264b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mVideoPreview = (VideoPreview) findViewById(R.id.camera_preview); 265b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mVideoPreview.setAspectRatio(VIDEO_ASPECT_RATIO); 266b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 267b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // don't set mSurfaceHolder here. We have it set ONLY within 268b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // surfaceCreated / surfaceDestroyed, other parts of the code 269b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // assume that when it is set, the surface is also set. 270b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project SurfaceHolder holder = mVideoPreview.getHolder(); 271b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project holder.addCallback(this); 272b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 273b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 274b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mPostPictureAlert = findViewById(R.id.post_picture_panel); 275b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 276b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int[] ids = new int[]{R.id.play, R.id.share, R.id.discard, 277b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project R.id.cancel, R.id.attach}; 278b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project for (int id : ids) { 279b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project findViewById(id).setOnClickListener(this); 280b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 281b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 282b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mShutterButton = (ShutterButton) findViewById(R.id.shutter_button); 283b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mShutterButton.setOnShutterButtonListener(this); 284b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mRecordingTimeView = (TextView) findViewById(R.id.recording_time); 285b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mVideoFrame = (ImageView) findViewById(R.id.video_frame); 2869bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mIsVideoCaptureIntent = isVideoCaptureIntent(); 2879bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (!mIsVideoCaptureIntent) { 2889bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mLastPictureButton = (ImageView) findViewById(R.id.last_picture_button); 2899bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mLastPictureButton.setOnClickListener(this); 2909bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang Drawable frame = getResources().getDrawable(R.drawable.frame_thumbnail); 2919bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mThumbController = new ThumbnailController(mLastPictureButton, 2929bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang frame, mContentResolver); 2939bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mThumbController.loadData(ImageManager.getLastVideoThumbPath()); 2949bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 295b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 296b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 297e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project private void startShareVideoActivity() { 2988d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project if (mCurrentVideoFileLength > SHARE_FILE_LENGTH_LIMIT) { 299e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project Toast.makeText(VideoCamera.this, 300e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project R.string.too_large_to_attach, Toast.LENGTH_LONG).show(); 301e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project return; 302e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project } 303e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project Intent intent = new Intent(); 304e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project intent.setAction(Intent.ACTION_SEND); 305e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project intent.setType("video/3gpp"); 306e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project intent.putExtra(Intent.EXTRA_STREAM, mCurrentVideoUri); 307e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project try { 308e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project startActivity(Intent.createChooser(intent, getText(R.string.sendVideo))); 309e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project } catch (android.content.ActivityNotFoundException ex) { 310e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project Toast.makeText(VideoCamera.this, R.string.no_way_to_share_video, Toast.LENGTH_SHORT).show(); 311e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project } 312e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project } 313e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project 314b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void onClick(View v) { 315b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project switch (v.getId()) { 316b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 317b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case R.id.gallery: 318b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project MenuHelper.gotoCameraVideoGallery(this); 319b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 320b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 321b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case R.id.attach: 322b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project doReturnToCaller(true); 323b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 324b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 325b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case R.id.cancel: 326b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project doReturnToCaller(false); 327b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 328b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 329b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case R.id.discard: { 3307638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen Runnable deleteCallback = new Runnable() { 3317638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen public void run() { 3327638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen discardCurrentVideoAndStartPreview(); 3337638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen } 3347638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen }; 3357638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen MenuHelper.deleteVideo(this, deleteCallback); 336b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 337b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 338b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 339b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case R.id.share: { 340e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project startShareVideoActivity(); 341b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 342b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 343b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 344b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case R.id.play: { 345b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project doPlayCurrentVideo(); 346b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 347b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 348de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 349de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project case R.id.last_picture_button: { 3509bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang stopVideoRecordingAndShowAlert(); 351de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project break; 352de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 353b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 354b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 355b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 356b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void onShutterButtonFocus(ShutterButton button, boolean pressed) { 357de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project // Do nothing (everything happens in onShutterButtonClick). 358de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 359de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 360de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project public void onShutterButtonClick(ShutterButton button) { 361b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project switch (button.getId()) { 362b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case R.id.shutter_button: 363de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project if (mMediaRecorderRecording) { 3649bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (mIsVideoCaptureIntent) { 365de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project stopVideoRecordingAndShowAlert(); 366b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 3679bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang stopVideoRecordingAndGetThumbnail(); 3689bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang initializeVideo(); 3699bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 3709bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } else if (isAlertVisible()) { 3719bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (mIsVideoCaptureIntent) { 3729bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang discardCurrentVideoAndStartPreview(); 3739bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } else { 3749bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang hideAlertAndStartVideoRecording(); 375b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 376de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } else { 377de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project startVideoRecording(); 378b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 379b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 380b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 381b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 382b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 383b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void doPlayCurrentVideo() { 384b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.e(TAG, "Playing current video: " + mCurrentVideoUri); 385b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Intent intent = new Intent(Intent.ACTION_VIEW, mCurrentVideoUri); 386b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project try { 387b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project startActivity(intent); 388b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } catch (android.content.ActivityNotFoundException ex) { 389b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.e(TAG, "Couldn't view video " + mCurrentVideoUri, ex); 390b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 391b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 392b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 393b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void discardCurrentVideoAndStartPreview() { 394b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project deleteCurrentVideo(); 3959bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang hideAlertAndStartPreview(); 396b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 397b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 398b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private OnScreenHint mStorageHint; 399b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 4009a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project private void updateAndShowStorageHint(boolean mayHaveSd) { 4019a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project mStorageStatus = getStorageStatus(mayHaveSd); 4029a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project showStorageHint(); 4039a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project } 4049a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project 4059a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project private void showStorageHint() { 406b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String errorMessage = null; 4079a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project switch (mStorageStatus) { 4089a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project case STORAGE_STATUS_NONE: 409b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project errorMessage = getString(R.string.no_storage); 4109a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project break; 4119a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project case STORAGE_STATUS_LOW: 412b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project errorMessage = getString(R.string.spaceIsLow_content); 413b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 414b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (errorMessage != null) { 415b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mStorageHint == null) { 416b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mStorageHint = OnScreenHint.makeText(this, errorMessage); 417b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 418b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mStorageHint.setText(errorMessage); 419b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 420b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mStorageHint.show(); 421b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else if (mStorageHint != null) { 422b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mStorageHint.cancel(); 423b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mStorageHint = null; 424b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 425b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 426b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 4279a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project private int getStorageStatus(boolean mayHaveSd) { 4289a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project long remaining = mayHaveSd ? getAvailableStorage() : NO_STORAGE_ERROR; 4299a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project if (remaining == NO_STORAGE_ERROR) { 4309a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project return STORAGE_STATUS_NONE; 4319a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project } 4329a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project return remaining < LOW_STORAGE_THRESHOLD 4339a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project ? STORAGE_STATUS_LOW : STORAGE_STATUS_OK; 4349a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project } 4359a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project 436b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 437b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void onResume() { 438b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project super.onResume(); 439b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 440b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenTimeoutLong(); 441b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 442b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mPausing = false; 443b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 444b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // install an intent filter to receive SD card related events. 445b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MEDIA_MOUNTED); 446b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project intentFilter.addAction(Intent.ACTION_MEDIA_EJECT); 447b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project intentFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED); 448b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_STARTED); 449b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED); 450b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project intentFilter.addDataScheme("file"); 451b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project registerReceiver(mReceiver, intentFilter); 4529a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project mStorageStatus = getStorageStatus(true); 4539a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project 4549a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project mHandler.postDelayed(new Runnable() { 4559a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project public void run() { 4569a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project showStorageHint(); 4579a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project } 4589a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project }, 200); 459b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 4609bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang initializeVideo(); 461b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 462b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 463b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 464b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void onStop() { 465b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenTimeoutSystemDefault(); 466b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project super.onStop(); 467b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 468b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 469b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 470b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project protected void onPause() { 471b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project super.onPause(); 472b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 4739bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // This is similar to what mShutterButton.performClick() does, 4749bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // but not quite the same. 4759bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (mMediaRecorderRecording) { 4769bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (mIsVideoCaptureIntent) { 4779bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang stopVideoRecordingAndShowAlert(); 4789bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } else { 4799bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang stopVideoRecordingAndGetThumbnail(); 4809bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 4819bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } else { 4829bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang stopVideoRecording(); 4839bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 484b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 485b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mPausing = true; 486b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 4879c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project unregisterReceiver(mReceiver); 488b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenTimeoutSystemDefault(); 489b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 4909bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (!mIsVideoCaptureIntent) { 4919bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mThumbController.storeData(ImageManager.getLastVideoThumbPath()); 4929bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 493095afa19556bf550262e3cccb9edacc04e6f726aOwen Lin 494b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mStorageHint != null) { 495b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mStorageHint.cancel(); 496b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mStorageHint = null; 497b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 498b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 499b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 500b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 501b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public boolean onKeyDown(int keyCode, KeyEvent event) { 502b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenTimeoutLong(); 503b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 504b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project switch (keyCode) { 505b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case KeyEvent.KEYCODE_BACK: 506b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mMediaRecorderRecording) { 507de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mShutterButton.performClick(); 508b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 5099bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } else if(isAlertVisible()) { 5109bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang hideAlertAndStartPreview(); 511b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 512b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 513b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 514b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case KeyEvent.KEYCODE_CAMERA: 515b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (event.getRepeatCount() == 0) { 516de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mShutterButton.performClick(); 517b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 518b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 519de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project break; 520b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case KeyEvent.KEYCODE_DPAD_CENTER: 521b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (event.getRepeatCount() == 0) { 522de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mShutterButton.performClick(); 523de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project return true; 524b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 525b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 526b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case KeyEvent.KEYCODE_MENU: 527b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mMediaRecorderRecording) { 528de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mShutterButton.performClick(); 529b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 530b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 531b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 532b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 533b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 534b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return super.onKeyDown(keyCode, event); 535b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 536b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 537b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 538b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public boolean onKeyUp(int keyCode, KeyEvent event) { 539b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project switch(keyCode) { 540b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case KeyEvent.KEYCODE_CAMERA: 541b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mShutterButton.setPressed(false); 542b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 543b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 544b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return super.onKeyUp(keyCode, event); 545b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 546b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 547b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 548314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber if (mPausing) { 549314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber // We're pausing, the screen is off and we already stopped 550314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber // video recording. We don't want to start the camera again 551314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber // in this case in order to conserve power. 552314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber // The fact that surfaceChanged is called _after_ an onPause appears 553314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber // to be legitimate since in that case the lockscreen always returns 554314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber // to portrait orientation possibly triggering the notification. 555314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber return; 556314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber } 557314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber 558b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project stopVideoRecording(); 559b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project initializeVideo(); 560b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 561b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 562b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void surfaceCreated(SurfaceHolder holder) { 563b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mSurfaceHolder = holder; 564b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 565b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 566b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void surfaceDestroyed(SurfaceHolder holder) { 567b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mSurfaceHolder = null; 568b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 569b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 570b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project void gotoGallery() { 571b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project MenuHelper.gotoCameraVideoGallery(this); 572b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 573b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 574b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 575b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public boolean onPrepareOptionsMenu(Menu menu) { 576b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project super.onPrepareOptionsMenu(menu); 577b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 578b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project for (int i = 1; i <= MenuHelper.MENU_ITEM_MAX; i++) { 579b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (i != MenuHelper.GENERIC_ITEM) { 580b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project menu.setGroupVisible(i, false); 581b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 582b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 583b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 584b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project menu.setGroupVisible(MenuHelper.VIDEO_MODE_ITEM, true); 585b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 586b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 587b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 588b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 589b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public boolean onCreateOptionsMenu(Menu menu) { 590b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project super.onCreateOptionsMenu(menu); 591b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 5929bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (mIsVideoCaptureIntent) { 593b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // No options menu for attach mode. 594b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return false; 595b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 596b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project addBaseMenuItems(menu); 597095afa19556bf550262e3cccb9edacc04e6f726aOwen Lin int menuFlags = MenuHelper.INCLUDE_ALL & ~MenuHelper.INCLUDE_ROTATE_MENU 598095afa19556bf550262e3cccb9edacc04e6f726aOwen Lin & ~MenuHelper.INCLUDE_DETAILS_MENU; 599b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project MenuHelper.addImageMenuItems( 600b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project menu, 601095afa19556bf550262e3cccb9edacc04e6f726aOwen Lin menuFlags, 602b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project false, 603b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project VideoCamera.this, 604b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mHandler, 605b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 606b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // Handler for deletion 607b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project new Runnable() { 608b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void run() { 609b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // What do we do here? 610b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // mContentResolver.delete(uri, null, null); 611b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 612b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project }, 613b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project new MenuHelper.MenuInvoker() { 614b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void run(final MenuHelper.MenuCallback cb) { 615b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 616b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project }); 617b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 618b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project MenuItem gallery = menu.add(MenuHelper.IMAGE_SAVING_ITEM, MENU_SAVE_GALLERY_PHOTO, 0, 619b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project R.string.camera_gallery_photos_text).setOnMenuItemClickListener( 620b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project new MenuItem.OnMenuItemClickListener() { 621b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public boolean onMenuItemClick(MenuItem item) { 622b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project gotoGallery(); 623b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 624b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 625b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project }); 626b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project gallery.setIcon(android.R.drawable.ic_menu_gallery); 627b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 628b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 629b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 630b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 631b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private boolean isVideoCaptureIntent() { 632b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String action = getIntent().getAction(); 633b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return (MediaStore.ACTION_VIDEO_CAPTURE.equals(action)); 634b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 635b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 636b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void doReturnToCaller(boolean success) { 637b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Intent resultIntent = new Intent(); 638b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int resultCode; 639b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (success) { 640b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project resultCode = RESULT_OK; 641b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project resultIntent.setData(mCurrentVideoUri); 642b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 643b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project resultCode = RESULT_CANCELED; 644b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 645b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setResult(resultCode, resultIntent); 646b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project finish(); 647b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 648b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 649b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project /** 650b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * Returns 651b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * @return number of bytes available, or an ERROR code. 652b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project */ 653b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static long getAvailableStorage() { 654b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project try { 655b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (!ImageManager.hasStorage()) { 656b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return NO_STORAGE_ERROR; 657b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 658b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String storageDirectory = Environment.getExternalStorageDirectory().toString(); 659b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project StatFs stat = new StatFs(storageDirectory); 660b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return ((long)stat.getAvailableBlocks() * (long)stat.getBlockSize()); 661b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 662b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } catch (Exception ex) { 663b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // if we can't stat the filesystem then we don't know how many 664b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // free bytes exist. It might be zero but just leave it 665b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // blank since we really don't know. 666b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return CANNOT_STAT_ERROR; 667b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 668b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 669b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 670b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void cleanupEmptyFile() { 671b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mCameraVideoFilename != null) { 672b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project File f = new File(mCameraVideoFilename); 673b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (f.length() == 0 && f.delete()) { 674b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Empty video file deleted: " + mCameraVideoFilename); 675b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCameraVideoFilename = null; 676b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 677b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 678b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 679b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 6809bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // initializeVideo() starts preview and prepare media recorder. 681b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // Returns false if initializeVideo fails 682b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private boolean initializeVideo() { 683b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "initializeVideo"); 6849bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 6859bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // We will call initializeVideo() again when the alert is hidden. 6869bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (isAlertVisible()) return false; 6879bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 688b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Intent intent = getIntent(); 689b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Bundle myExtras = intent.getExtras(); 690b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 6919bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (mIsVideoCaptureIntent && myExtras != null) { 692b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Uri saveUri = (Uri) myExtras.getParcelable(MediaStore.EXTRA_OUTPUT); 693b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (saveUri != null) { 694b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project try { 695b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCameraVideoFileDescriptor = mContentResolver. 696b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project openFileDescriptor(saveUri, "rw").getFileDescriptor(); 697b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoUri = saveUri; 698b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 699b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project catch (java.io.FileNotFoundException ex) { 700b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // invalid uri 701b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.e(TAG, ex.toString()); 702b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 703b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 704b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 705b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project releaseMediaRecorder(); 706b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 707b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mSurfaceHolder == null) { 708b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "SurfaceHolder is null"); 709b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return false; 710b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 711b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 712b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder = new MediaRecorder(); 713b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 714b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (DEBUG_SUPPRESS_AUDIO_RECORDING) { 715b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "DEBUG_SUPPRESS_AUDIO_RECORDING is true."); 716b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 717b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); 718b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 719b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); 720b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); 721b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 7228d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project mMediaRecorder.setMaxDuration(MAX_RECORDING_DURATION_MS); 7238d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project 7249a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project if (mStorageStatus != STORAGE_STATUS_OK) { 725b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setOutputFile("/dev/null"); 726b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 727b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // We try Uri in intent first. If it doesn't work, use our own instead. 728b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mCameraVideoFileDescriptor != null) { 729b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setOutputFile(mCameraVideoFileDescriptor); 730b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 731b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project createVideoPath(); 732b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setOutputFile(mCameraVideoFilename); 733b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 734b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 735b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 736b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project boolean videoQualityHigh = getBooleanPreference(CameraSettings.KEY_VIDEO_QUALITY, 737b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project CameraSettings.DEFAULT_VIDEO_QUALITY_VALUE); 738b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 739b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (intent.hasExtra(MediaStore.EXTRA_VIDEO_QUALITY)) { 740b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int extraVideoQuality = intent.getIntExtra(MediaStore.EXTRA_VIDEO_QUALITY, 0); 741b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project videoQualityHigh = (extraVideoQuality > 0); 742b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 743b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 744b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // Use the same frame rate for both, since internally 745b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // if the frame rate is too large, it can cause camera to become 746b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // unstable. We need to fix the MediaRecorder to disable the support 747b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // of setting frame rate for now. 748b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setVideoFrameRate(20); 749b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (videoQualityHigh) { 750b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setVideoSize(352,288); 751b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 752b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setVideoSize(176,144); 753b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 754b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263); 755b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (!DEBUG_SUPPRESS_AUDIO_RECORDING) { 756b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); 757b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 758b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface()); 759de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 760de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project long remaining = getAvailableStorage(); 761de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project // remaining >= LOW_STORAGE_THRESHOLD at this point, reserve a quarter 762de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project // of that to make it more likely that recording can complete successfully. 763de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project try { 764de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mMediaRecorder.setMaxFileSize(remaining - LOW_STORAGE_THRESHOLD / 4); 765de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } catch (RuntimeException exception) { 766de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project // We are going to ignore failure of setMaxFileSize here, as 767de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project // a) The composer selected may simply not support it, or 768de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project // b) The underlying media framework may not handle 64-bit range 769de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project // on the size restriction. 770de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 771de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 772b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project try { 773b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.prepare(); 774b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } catch (IOException exception) { 775b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.e(TAG, "prepare failed for " + mCameraVideoFilename); 776b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project releaseMediaRecorder(); 777b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // TODO: add more exception handling logic here 778b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return false; 779b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 780b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorderRecording = false; 7819bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 7829bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (!mIsVideoCaptureIntent && !mThumbController.isUriValid()) { 7839bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang updateLastVideo(); 7849bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 7859bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 7869bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (!mIsVideoCaptureIntent) { 7879bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mThumbController.updateDisplayIfNeeded(); 7889bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 7899bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 790b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 791b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 792b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 793b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void releaseMediaRecorder() { 794b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Releasing media recorder."); 795b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mMediaRecorder != null) { 796b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project cleanupEmptyFile(); 797b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.reset(); 798b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.release(); 799b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder = null; 800b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 801b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 802b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 803b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private int getIntPreference(String key, int defaultValue) { 804b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String s = mPreferences.getString(key, ""); 805b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int result = defaultValue; 806b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project try { 807b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project result = Integer.parseInt(s); 808b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } catch (NumberFormatException e) { 809b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // Ignore, result is already the default value. 810b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 811b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return result; 812b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 813b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 814b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private boolean getBooleanPreference(String key, boolean defaultValue) { 815b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return getIntPreference(key, defaultValue ? 1 : 0) != 0; 816b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 817b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 818b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void createVideoPath() { 819b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project long dateTaken = System.currentTimeMillis(); 820b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String title = createName(dateTaken); 821b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String displayName = title + ".3gp"; // Used when emailing. 822b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String cameraDirPath = ImageManager.CAMERA_IMAGE_BUCKET_NAME; 823b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project File cameraDir = new File(cameraDirPath); 824b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project cameraDir.mkdirs(); 825b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project SimpleDateFormat dateFormat = new SimpleDateFormat( 826b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project getString(R.string.video_file_name_format)); 827b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Date date = new Date(dateTaken); 828b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String filepart = dateFormat.format(date); 829b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String filename = cameraDirPath + "/" + filepart + ".3gp"; 830b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project ContentValues values = new ContentValues(7); 831b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project values.put(Video.Media.TITLE, title); 832b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project values.put(Video.Media.DISPLAY_NAME, displayName); 833b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project values.put(Video.Media.DESCRIPTION, ""); 834b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project values.put(Video.Media.DATE_TAKEN, dateTaken); 835b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project values.put(Video.Media.MIME_TYPE, "video/3gpp"); 836b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project values.put(Video.Media.DATA, filename); 837b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCameraVideoFilename = filename; 838b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Current camera video filename: " + mCameraVideoFilename); 839b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoValues = values; 840b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 841b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 842b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void registerVideo() { 843b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mCameraVideoFileDescriptor == null) { 844b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Uri videoTable = Uri.parse("content://media/external/video/media"); 845b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoUri = mContentResolver.insert(videoTable, 846b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoValues); 847b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Current video URI: " + mCurrentVideoUri); 848b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 849b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoValues = null; 850b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 851b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 852b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void deleteCurrentVideo() { 853b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mCurrentVideoFilename != null) { 854b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project deleteVideoFile(mCurrentVideoFilename); 855b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoFilename = null; 856b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 857b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mCurrentVideoUri != null) { 858b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mContentResolver.delete(mCurrentVideoUri, null, null); 859b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoUri = null; 860b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 861de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project updateAndShowStorageHint(true); 862b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 863b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 864b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void deleteVideoFile(String fileName) { 865b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Deleting video " + fileName); 866b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project File f = new File(fileName); 867b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (! f.delete()) { 868b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Could not delete " + fileName); 869b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 870b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 871b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 872b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void addBaseMenuItems(Menu menu) { 873b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project MenuHelper.addSwitchModeMenuItem(menu, this, false); 874b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project { 875b64d345c9d51cabce43b5191532a0c185d2a70a5The 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() { 876b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public boolean onMenuItemClick(MenuItem item) { 877b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project gotoGallery(); 878b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 879b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 880b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project }); 881b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project gallery.setIcon(android.R.drawable.ic_menu_gallery); 882b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mGalleryItems.add(gallery); 883b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 884b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project { 885b64d345c9d51cabce43b5191532a0c185d2a70a5The 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() { 886b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public boolean onMenuItemClick(MenuItem item) { 887b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project gotoGallery(); 888b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 889b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 890b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project }); 891b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project gallery.setIcon(android.R.drawable.ic_menu_gallery); 892b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mGalleryItems.add(gallery); 893b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 894b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 895b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project MenuItem item = menu.add(MenuHelper.GENERIC_ITEM, MENU_SETTINGS, 0, R.string.settings).setOnMenuItemClickListener(new OnMenuItemClickListener() { 896b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public boolean onMenuItemClick(MenuItem item) { 897b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Intent intent = new Intent(); 898b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project intent.setClass(VideoCamera.this, CameraSettings.class); 899b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project startActivity(intent); 900b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 901b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 902b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project }); 903b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project item.setIcon(android.R.drawable.ic_menu_preferences); 904b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 905b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 906b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // from MediaRecorder.OnErrorListener 907b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void onError(MediaRecorder mr, int what, int extra) { 908b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (what == MediaRecorder.MEDIA_RECORDER_ERROR_UNKNOWN) { 909b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // We may have run out of space on the sdcard. 910b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project stopVideoRecording(); 9119a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project updateAndShowStorageHint(true); 912b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 913b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 914b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 9158d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project // from MediaRecorder.OnInfoListener 9168d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project public void onInfo(MediaRecorder mr, int what, int extra) { 9178d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) { 918de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mShutterButton.performClick(); 919de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } else if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED) { 920de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mShutterButton.performClick(); 921de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project updateAndShowStorageHint(true); 9228d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project } 9238d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project } 9248d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project 9259c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project /* 9269c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project * Make sure we're not recording music playing in the background, ask 9279c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project * the MediaPlaybackService to pause playback. 9289c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project */ 9299c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project private void pauseAudioPlayback() { 9309c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project // Shamelessly copied from MediaPlaybackService.java, which 9319c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project // should be public, but isn't. 9329c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project Intent i = new Intent("com.android.music.musicservicecommand"); 9339c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project i.putExtra("command", "pause"); 9349c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project 9359c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project sendBroadcast(i); 9369c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project } 9379c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project 938b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void startVideoRecording() { 939b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "startVideoRecording"); 940b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (!mMediaRecorderRecording) { 941b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 9429a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project if (mStorageStatus != STORAGE_STATUS_OK) { 943b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Storage issue, ignore the start request"); 944b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return; 945b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 946b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 947b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // Check mMediaRecorder to see whether it is initialized or not. 948b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mMediaRecorder == null && initializeVideo() == false ) { 949b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.e(TAG, "Initialize video (MediaRecorder) failed."); 950b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return; 951b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 952b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 9539c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project pauseAudioPlayback(); 9549c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project 955b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project try { 956b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setOnErrorListener(this); 9578d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project mMediaRecorder.setOnInfoListener(this); 958b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.start(); // Recording is now started 959b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } catch (RuntimeException e) { 960b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.e(TAG, "Could not start media recorder. ", e); 961b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return; 962b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 963b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorderRecording = true; 964b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mRecordingStartTime = SystemClock.uptimeMillis(); 965b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project updateRecordingIndicator(true); 966b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mRecordingTimeView.setText(""); 967b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mRecordingTimeView.setVisibility(View.VISIBLE); 968b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mHandler.sendEmptyMessage(UPDATE_RECORD_TIME); 969b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenTimeoutInfinite(); 970de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project hideLastPictureButton(); 971b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 972b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 973b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 974b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void updateRecordingIndicator(boolean showRecording) { 975b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int drawableId = showRecording ? R.drawable.ic_camera_bar_indicator_record 976b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project : R.drawable.ic_camera_indicator_video; 977b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Drawable drawable = getResources().getDrawable(drawableId); 978b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mShutterButton.setImageDrawable(drawable); 979b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 980b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 9819bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private void stopVideoRecordingAndGetThumbnail() { 9829bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang stopVideoRecording(); 9839bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang acquireVideoThumb(); 984b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 985b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 986de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project private void stopVideoRecordingAndShowAlert() { 987de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project stopVideoRecording(); 9889bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang showAlert(); 989de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 990de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 9919bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private void showAlert() { 992b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int[] pickIds = {R.id.attach, R.id.cancel}; 993b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int[] normalIds = {R.id.gallery, R.id.share, R.id.discard}; 994b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int[] alwaysOnIds = {R.id.play}; 995b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int[] hideIds = pickIds; 996b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int[] connectIds = normalIds; 9979bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (mIsVideoCaptureIntent) { 998b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project hideIds = normalIds; 999b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project connectIds = pickIds; 1000b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1001b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project for(int id : hideIds) { 1002b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mPostPictureAlert.findViewById(id).setVisibility(View.GONE); 1003b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 10048d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project ActionMenuButton shareButton = 10058d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project (ActionMenuButton) mPostPictureAlert.findViewById(R.id.share); 10068d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project shareButton.setRestricted( 10078d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project mCurrentVideoFileLength > SHARE_FILE_LENGTH_LIMIT); 1008b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project connectAndFadeIn(connectIds); 1009b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project connectAndFadeIn(alwaysOnIds); 1010de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project hideLastPictureButton(); 1011b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mPostPictureAlert.setVisibility(View.VISIBLE); 10129bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 10139bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // There are two cases we are here: 10149bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // (1) We are in a capture video intent, and we are reviewing the video 1015095afa19556bf550262e3cccb9edacc04e6f726aOwen Lin // we just taken. 10169bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // (2) The thumbnail button is clicked: we review the video associated 10179bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // with the thumbnail. 10189bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // For the second case, we copy the associated URI and filename to 10199bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // mCurrentVideoUri and mCurrentVideoFilename, so the video frame shown 10209bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // and the target for actions (play, delete, ...) will be correct. 10219bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 10229bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (!mIsVideoCaptureIntent) { 10239bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mCurrentVideoUri = mThumbController.getUri(); 10249bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mCurrentVideoFilename = getDataPath(mCurrentVideoUri); 10259bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 10269bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 10279bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang String path = mCurrentVideoFilename; 10289bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (path != null) { 10299bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang Bitmap videoFrame = ImageManager.createVideoThumbnail(path); 10309bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mVideoFrame.setImageBitmap(videoFrame); 10319bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mVideoFrame.setVisibility(View.VISIBLE); 10329bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 1033b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1034b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 10359bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private void hideAlert() { 1036de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mVideoFrame.setVisibility(View.INVISIBLE); 1037de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mPostPictureAlert.setVisibility(View.INVISIBLE); 1038de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project showLastPictureButton(); 1039de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 1040de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 1041b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void connectAndFadeIn(int[] connectIds) { 1042b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project for(int id : connectIds) { 1043b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project View view = mPostPictureAlert.findViewById(id); 1044b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project view.setOnClickListener(this); 1045b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Animation animation = new AlphaAnimation(0F, 1F); 1046b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project animation.setDuration(500); 10479bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang view.startAnimation(animation); 1048b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1049b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1050b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 10519bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private boolean isAlertVisible() { 1052b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return mPostPictureAlert.getVisibility() == View.VISIBLE; 1053b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1054b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1055b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void stopVideoRecording() { 1056b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "stopVideoRecording"); 1057b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project boolean needToRegisterRecording = false; 1058b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mMediaRecorderRecording || mMediaRecorder != null) { 1059b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mMediaRecorderRecording && mMediaRecorder != null) { 1060b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project try { 1061b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setOnErrorListener(null); 10628d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project mMediaRecorder.setOnInfoListener(null); 1063b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.stop(); 1064b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } catch (RuntimeException e) { 1065b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.e(TAG, "stop fail: " + e.getMessage()); 1066b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 10678d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project 1068b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoFilename = mCameraVideoFilename; 10698d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project try { 10708d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project mCurrentVideoFileLength = new File(mCurrentVideoFilename).length(); 10718d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project } catch (RuntimeException e) { 10728d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project Log.e(TAG, "get file length fail: " + e.getMessage()); 10738d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project mCurrentVideoFileLength = 0; 10748d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project } 1075b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Setting current video filename: " + mCurrentVideoFilename); 1076b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project needToRegisterRecording = true; 1077b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorderRecording = false; 1078b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1079b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project releaseMediaRecorder(); 1080b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project updateRecordingIndicator(false); 1081b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mRecordingTimeView.setVisibility(View.GONE); 1082b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenTimeoutLong(); 1083b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 10849a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project if (needToRegisterRecording && mStorageStatus == STORAGE_STATUS_OK) { 10859a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project registerVideo(); 10869a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project } 1087b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1088b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCameraVideoFilename = null; 1089b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCameraVideoFileDescriptor = null; 1090b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1091b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1092b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void setScreenTimeoutSystemDefault() { 1093b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mHandler.removeMessages(CLEAR_SCREEN_DELAY); 1094b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project clearScreenOnFlag(); 1095b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1096b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1097b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void setScreenTimeoutLong() { 1098b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mHandler.removeMessages(CLEAR_SCREEN_DELAY); 1099b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenOnFlag(); 1100b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mHandler.sendEmptyMessageDelayed(CLEAR_SCREEN_DELAY, SCREEN_DELAY); 1101b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1102b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1103b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void setScreenTimeoutInfinite() { 1104b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mHandler.removeMessages(CLEAR_SCREEN_DELAY); 1105b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenOnFlag(); 1106b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1107b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1108b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void clearScreenOnFlag() { 1109b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Window w = getWindow(); 1110b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project final int keepScreenOnFlag = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; 1111b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if ((w.getAttributes().flags & keepScreenOnFlag) != 0) { 1112b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project w.clearFlags(keepScreenOnFlag); 1113b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1114b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1115b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1116b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void setScreenOnFlag() { 1117b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Window w = getWindow(); 1118b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project final int keepScreenOnFlag = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; 1119b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if ((w.getAttributes().flags & keepScreenOnFlag) == 0) { 1120b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project w.addFlags(keepScreenOnFlag); 1121b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1122b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1123b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 11249bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private void hideAlertAndStartPreview() { 11259bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang hideAlert(); 11269bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang initializeVideo(); 1127b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1128b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 11299bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private void hideAlertAndStartVideoRecording() { 11309bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang hideAlert(); 11319bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang startVideoRecording(); 1132b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1133b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 11349bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private void acquireVideoThumb() { 11359bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang Bitmap videoFrame = ImageManager.createVideoThumbnail(mCurrentVideoFilename); 11369bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mThumbController.setData(mCurrentVideoUri, videoFrame); 1137de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 1138de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 11399bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private void showLastPictureButton() { 11409bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (!mIsVideoCaptureIntent) { 11419bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mLastPictureButton.setVisibility(View.VISIBLE); 1142de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 11439bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 1144de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 11459bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private void hideLastPictureButton() { 11469bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (!mIsVideoCaptureIntent) { 11479bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mLastPictureButton.setVisibility(View.INVISIBLE); 11489bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 1149de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 1150de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 11519bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private static ImageManager.DataLocation dataLocation() { 11529bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang return ImageManager.DataLocation.EXTERNAL; 1153de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 1154de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 11559bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private void updateLastVideo() { 11569bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang ImageManager.IImageList list = ImageManager.instance().allImages( 11579bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang this, 11589bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mContentResolver, 11599bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang dataLocation(), 11609bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang ImageManager.INCLUDE_VIDEOS, 11619bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang ImageManager.SORT_ASCENDING, 11629bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang ImageManager.CAMERA_IMAGE_BUCKET_ID); 11639bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang int count = list.getCount(); 11649bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (count > 0) { 11659bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang ImageManager.IImage image = list.getImageAt(count-1); 11669bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang Uri uri = image.fullSizeImageUri(); 11679bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mThumbController.setData(uri, image.miniThumbBitmap()); 11689bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } else { 11699bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mThumbController.setData(null, null); 11709bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 11719bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang list.deactivate(); 1172b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1173b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 11749bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private static final String[] DATA_PATH_PROJECTION = new String[] { 11759bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang "_data" 11769bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang }; 11779bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 11789bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private String getDataPath(Uri uri) { 11799bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang Cursor c = null; 11809bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang try { 11819bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang c = mContentResolver.query(uri, DATA_PATH_PROJECTION, null, null, null); 11829bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (c != null && c.moveToFirst()) { 11839bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang return c.getString(0); 11849bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } else { 11859bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang return null; 11869bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 11879bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } finally { 11889bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (c != null) c.close(); 1189b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1190b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1191b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project} 1192