VideoCamera.java revision 101d528d59f447847d5c6b7578642132c2b76f4f
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 19101d528d59f447847d5c6b7578642132c2b76f4fOwen Linimport com.android.camera.gallery.IImage; 20101d528d59f447847d5c6b7578642132c2b76f4fOwen Linimport com.android.camera.gallery.IImageList; 21101d528d59f447847d5c6b7578642132c2b76f4fOwen Linimport com.android.camera.gallery.Util; 22101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin 23b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport java.io.File; 24b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport java.io.FileDescriptor; 25b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport java.io.IOException; 26b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport java.text.SimpleDateFormat; 27b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport java.util.ArrayList; 28b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport java.util.Date; 29b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 30b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.app.Activity; 31b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.BroadcastReceiver; 32b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.ContentResolver; 33b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.ContentValues; 34b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.Context; 35b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.Intent; 36b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.IntentFilter; 37b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.SharedPreferences; 38095afa19556bf550262e3cccb9edacc04e6f726aOwen Linimport android.database.Cursor; 39b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.graphics.Bitmap; 40b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.graphics.drawable.Drawable; 41b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.location.LocationManager; 42b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.media.MediaRecorder; 43b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.net.Uri; 44b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.Bundle; 45b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.Environment; 46b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.Handler; 47b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.Message; 48b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.StatFs; 49b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.SystemClock; 50b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.preference.PreferenceManager; 51b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.provider.MediaStore; 52b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.provider.MediaStore.Video; 53b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.text.format.DateFormat; 54b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.util.Log; 55b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.KeyEvent; 56b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.Menu; 57b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.MenuItem; 58b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.SurfaceHolder; 59b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.View; 60b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.Window; 61b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.WindowManager; 62b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.MenuItem.OnMenuItemClickListener; 63b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.animation.AlphaAnimation; 64b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.animation.Animation; 65b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.widget.ImageView; 66b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.widget.TextView; 67b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.widget.Toast; 68b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 69b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectpublic class VideoCamera extends Activity implements View.OnClickListener, 708d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project ShutterButton.OnShutterButtonListener, SurfaceHolder.Callback, MediaRecorder.OnErrorListener, MediaRecorder.OnInfoListener { 71b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 72b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final String TAG = "videocamera"; 73b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 74b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final boolean DEBUG = true; 75b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final boolean DEBUG_SUPPRESS_AUDIO_RECORDING = DEBUG && false; 76b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 77b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final int CLEAR_SCREEN_DELAY = 4; 78b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final int UPDATE_RECORD_TIME = 5; 79b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 80b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final int SCREEN_DELAY = 2 * 60 * 1000; 81b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 82b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final long NO_STORAGE_ERROR = -1L; 83b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final long CANNOT_STAT_ERROR = -2L; 84b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final long LOW_STORAGE_THRESHOLD = 512L * 1024L; 85e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project private static final long SHARE_FILE_LENGTH_LIMIT = 3L * 1024L * 1024L; 86b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 879a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project private static final int STORAGE_STATUS_OK = 0; 889a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project private static final int STORAGE_STATUS_LOW = 1; 899a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project private static final int STORAGE_STATUS_NONE = 2; 909a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project 91b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public static final int MENU_SETTINGS = 6; 92b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public static final int MENU_GALLERY_PHOTOS = 7; 93b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public static final int MENU_GALLERY_VIDEOS = 8; 94b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public static final int MENU_SAVE_GALLERY_PHOTO = 34; 95b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public static final int MENU_SAVE_PLAY_VIDEO = 35; 96b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public static final int MENU_SAVE_SELECT_VIDEO = 36; 97b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public static final int MENU_SAVE_NEW_VIDEO = 37; 98b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 99b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project SharedPreferences mPreferences; 100b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 101b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final float VIDEO_ASPECT_RATIO = 176.0f / 144.0f; 102b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project VideoPreview mVideoPreview; 103b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project SurfaceHolder mSurfaceHolder = null; 104b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project ImageView mVideoFrame; 1059bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 1069bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private boolean mIsVideoCaptureIntent; 1079bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // mLastPictureButton and mThumbController 1089bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // are non-null only if isVideoCaptureIntent() is true; 109de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project private ImageView mLastPictureButton; 1109bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private ThumbnailController mThumbController; 111b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1128d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project private static final int MAX_RECORDING_DURATION_MS = 10 * 60 * 1000; 1138d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project 1149a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project private int mStorageStatus = STORAGE_STATUS_OK; 1159a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project 116b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private MediaRecorder mMediaRecorder; 117b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private boolean mMediaRecorderRecording = false; 118b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private long mRecordingStartTime; 119b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // The video file that the hardware camera is about to record into 120b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // (or is recording into.) 121b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private String mCameraVideoFilename; 122b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private FileDescriptor mCameraVideoFileDescriptor; 123b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 124b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // The video file that has already been recorded, and that is being 125b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // examined by the user. 126b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private String mCurrentVideoFilename; 1278d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project private long mCurrentVideoFileLength = 0L; 128b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private Uri mCurrentVideoUri; 129b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private ContentValues mCurrentVideoValues; 130b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 131b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project boolean mPausing = false; 132b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 133b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project static ContentResolver mContentResolver; 134b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 135b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int mCurrentZoomIndex = 0; 136b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 137b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private ShutterButton mShutterButton; 138b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private TextView mRecordingTimeView; 1398d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project private boolean mRecordingTimeCountsDown = false; 140b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 141b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project ArrayList<MenuItem> mGalleryItems = new ArrayList<MenuItem>(); 142b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 143b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project View mPostPictureAlert; 144b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project LocationManager mLocationManager = null; 145b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 146b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private Handler mHandler = new MainHandler(); 147b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 148b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project /** This Handler is used to post message back onto the main thread of the application */ 149b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private class MainHandler extends Handler { 150b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 151b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void handleMessage(Message msg) { 152b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project switch (msg.what) { 153b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 154b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case CLEAR_SCREEN_DELAY: { 155b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project clearScreenOnFlag(); 156b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 157b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 158b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 159b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case UPDATE_RECORD_TIME: { 160b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mMediaRecorderRecording) { 161b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project long now = SystemClock.uptimeMillis(); 162b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project long delta = now - mRecordingStartTime; 1638d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project 1648d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project // Starting a minute before reaching the max duration 1658d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project // limit, we'll countdown the remaining time instead. 1668d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project boolean countdown_remaining_time = 1678d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project (delta >= MAX_RECORDING_DURATION_MS - 60000); 1688d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project 1698d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project if (countdown_remaining_time) { 1708d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project delta = Math.max(0, MAX_RECORDING_DURATION_MS - delta); 1718d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project } 1728d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project 1738d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project long seconds = (delta + 500) / 1000; // round to nearest 174b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project long minutes = seconds / 60; 175b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project long hours = minutes / 60; 176b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project long remainderMinutes = minutes - (hours * 60); 177b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project long remainderSeconds = seconds - (minutes * 60); 178b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 179b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String secondsString = Long.toString(remainderSeconds); 180b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (secondsString.length() < 2) { 181b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project secondsString = "0" + secondsString; 182b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 183b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String minutesString = Long.toString(remainderMinutes); 184b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (minutesString.length() < 2) { 185b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project minutesString = "0" + minutesString; 186b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 187b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String text = minutesString + ":" + secondsString; 188b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (hours > 0) { 189b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String hoursString = Long.toString(hours); 190b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (hoursString.length() < 2) { 191b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project hoursString = "0" + hoursString; 192b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 193b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project text = hoursString + ":" + text; 194b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 195b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mRecordingTimeView.setText(text); 1968d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project 1978d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project if (mRecordingTimeCountsDown != countdown_remaining_time) { 1988d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project // Avoid setting the color on every update, do it only 1998d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project // when it needs changing. 2008d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project 2018d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project mRecordingTimeCountsDown = countdown_remaining_time; 2028d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project 2038d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project int color = getResources().getColor( 2048d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project countdown_remaining_time ? R.color.recording_time_remaining_text 2058d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project : R.color.recording_time_elapsed_text); 2068d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project 2078d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project mRecordingTimeView.setTextColor(color); 2088d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project } 2098d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project 210b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // Work around a limitation of the T-Mobile G1: The T-Mobile 211b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // hardware blitter can't pixel-accurately scale and clip at the same time, 212b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // and the SurfaceFlinger doesn't attempt to work around this limitation. 213b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // In order to avoid visual corruption we must manually refresh the entire 214b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // surface view when changing any overlapping view's contents. 215b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mVideoPreview.invalidate(); 216b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mHandler.sendEmptyMessageDelayed(UPDATE_RECORD_TIME, 1000); 217b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 218b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 219b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 220b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 221b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project default: 222b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Unhandled message: " + msg.what); 223b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 224b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 225b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 226b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project }; 227b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 228b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 229b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 230b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void onReceive(Context context, Intent intent) { 231b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String action = intent.getAction(); 232b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (action.equals(Intent.ACTION_MEDIA_EJECT)) { 2339a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project updateAndShowStorageHint(false); 234b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project stopVideoRecording(); 235b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project initializeVideo(); 236b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else if (action.equals(Intent.ACTION_MEDIA_MOUNTED)) { 2379a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project updateAndShowStorageHint(true); 238b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project initializeVideo(); 239b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else if (action.equals(Intent.ACTION_MEDIA_UNMOUNTED)) { 240b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // SD card unavailable 2419a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project // handled in ACTION_MEDIA_EJECT 242b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else if (action.equals(Intent.ACTION_MEDIA_SCANNER_STARTED)) { 243b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Toast.makeText(VideoCamera.this, getResources().getString(R.string.wait), 5000); 244b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else if (action.equals(Intent.ACTION_MEDIA_SCANNER_FINISHED)) { 2459a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project updateAndShowStorageHint(true); 246b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 247b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 248b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project }; 249b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 250b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project static private String createName(long dateTaken) { 251b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return DateFormat.format("yyyy-MM-dd kk.mm.ss", dateTaken).toString(); 252b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 253b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 254b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project /** Called with the activity is first created. */ 255b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 256b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void onCreate(Bundle icicle) { 257b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project super.onCreate(icicle); 258b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 259b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); 260b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 261b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mPreferences = PreferenceManager.getDefaultSharedPreferences(this); 262b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mContentResolver = getContentResolver(); 263b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 264b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project //setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT); 265b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project requestWindowFeature(Window.FEATURE_PROGRESS); 266b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setContentView(R.layout.video_camera); 267b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 268b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mVideoPreview = (VideoPreview) findViewById(R.id.camera_preview); 269b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mVideoPreview.setAspectRatio(VIDEO_ASPECT_RATIO); 270b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 271b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // don't set mSurfaceHolder here. We have it set ONLY within 272b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // surfaceCreated / surfaceDestroyed, other parts of the code 273b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // assume that when it is set, the surface is also set. 274b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project SurfaceHolder holder = mVideoPreview.getHolder(); 275b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project holder.addCallback(this); 276b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 277b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 278b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mPostPictureAlert = findViewById(R.id.post_picture_panel); 279b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 280b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int[] ids = new int[]{R.id.play, R.id.share, R.id.discard, 281b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project R.id.cancel, R.id.attach}; 282b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project for (int id : ids) { 283b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project findViewById(id).setOnClickListener(this); 284b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 285b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 286b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mShutterButton = (ShutterButton) findViewById(R.id.shutter_button); 287b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mShutterButton.setOnShutterButtonListener(this); 288b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mRecordingTimeView = (TextView) findViewById(R.id.recording_time); 289b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mVideoFrame = (ImageView) findViewById(R.id.video_frame); 2909bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mIsVideoCaptureIntent = isVideoCaptureIntent(); 2919bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (!mIsVideoCaptureIntent) { 2929bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mLastPictureButton = (ImageView) findViewById(R.id.last_picture_button); 2939bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mLastPictureButton.setOnClickListener(this); 2949bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang Drawable frame = getResources().getDrawable(R.drawable.frame_thumbnail); 2959bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mThumbController = new ThumbnailController(mLastPictureButton, 2969bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang frame, mContentResolver); 2979bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mThumbController.loadData(ImageManager.getLastVideoThumbPath()); 2989bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 299b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 300b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 301e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project private void startShareVideoActivity() { 3028d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project if (mCurrentVideoFileLength > SHARE_FILE_LENGTH_LIMIT) { 303e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project Toast.makeText(VideoCamera.this, 304e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project R.string.too_large_to_attach, Toast.LENGTH_LONG).show(); 305e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project return; 306e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project } 307e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project Intent intent = new Intent(); 308e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project intent.setAction(Intent.ACTION_SEND); 309e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project intent.setType("video/3gpp"); 310e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project intent.putExtra(Intent.EXTRA_STREAM, mCurrentVideoUri); 311e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project try { 312e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project startActivity(Intent.createChooser(intent, getText(R.string.sendVideo))); 313e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project } catch (android.content.ActivityNotFoundException ex) { 314e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project Toast.makeText(VideoCamera.this, R.string.no_way_to_share_video, Toast.LENGTH_SHORT).show(); 315e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project } 316e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project } 317e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project 318b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void onClick(View v) { 319b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project switch (v.getId()) { 320b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 321b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case R.id.gallery: 322b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project MenuHelper.gotoCameraVideoGallery(this); 323b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 324b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 325b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case R.id.attach: 326b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project doReturnToCaller(true); 327b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 328b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 329b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case R.id.cancel: 330b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project doReturnToCaller(false); 331b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 332b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 333b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case R.id.discard: { 3347638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen Runnable deleteCallback = new Runnable() { 3357638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen public void run() { 3367638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen discardCurrentVideoAndStartPreview(); 3377638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen } 3387638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen }; 3397638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen MenuHelper.deleteVideo(this, deleteCallback); 340b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 341b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 342b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 343b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case R.id.share: { 344e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project startShareVideoActivity(); 345b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 346b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 347b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 348b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case R.id.play: { 349b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project doPlayCurrentVideo(); 350b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 351b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 352de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 353de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project case R.id.last_picture_button: { 3549bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang stopVideoRecordingAndShowAlert(); 355de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project break; 356de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 357b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 358b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 359b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 360b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void onShutterButtonFocus(ShutterButton button, boolean pressed) { 361de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project // Do nothing (everything happens in onShutterButtonClick). 362de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 363de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 364de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project public void onShutterButtonClick(ShutterButton button) { 365b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project switch (button.getId()) { 366b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case R.id.shutter_button: 367de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project if (mMediaRecorderRecording) { 3689bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (mIsVideoCaptureIntent) { 369de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project stopVideoRecordingAndShowAlert(); 370b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 3719bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang stopVideoRecordingAndGetThumbnail(); 3729bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang initializeVideo(); 3739bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 3749bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } else if (isAlertVisible()) { 3759bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (mIsVideoCaptureIntent) { 3769bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang discardCurrentVideoAndStartPreview(); 3779bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } else { 3789bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang hideAlertAndStartVideoRecording(); 379b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 380de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } else { 381de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project startVideoRecording(); 382b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 383b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 384b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 385b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 386b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 387b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void doPlayCurrentVideo() { 388b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.e(TAG, "Playing current video: " + mCurrentVideoUri); 389b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Intent intent = new Intent(Intent.ACTION_VIEW, mCurrentVideoUri); 390b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project try { 391b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project startActivity(intent); 392b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } catch (android.content.ActivityNotFoundException ex) { 393b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.e(TAG, "Couldn't view video " + mCurrentVideoUri, ex); 394b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 395b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 396b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 397b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void discardCurrentVideoAndStartPreview() { 398b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project deleteCurrentVideo(); 3999bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang hideAlertAndStartPreview(); 400b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 401b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 402b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private OnScreenHint mStorageHint; 403b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 4049a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project private void updateAndShowStorageHint(boolean mayHaveSd) { 4059a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project mStorageStatus = getStorageStatus(mayHaveSd); 4069a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project showStorageHint(); 4079a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project } 4089a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project 4099a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project private void showStorageHint() { 410b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String errorMessage = null; 4119a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project switch (mStorageStatus) { 4129a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project case STORAGE_STATUS_NONE: 413b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project errorMessage = getString(R.string.no_storage); 4149a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project break; 4159a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project case STORAGE_STATUS_LOW: 416b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project errorMessage = getString(R.string.spaceIsLow_content); 417b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 418b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (errorMessage != null) { 419b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mStorageHint == null) { 420b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mStorageHint = OnScreenHint.makeText(this, errorMessage); 421b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 422b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mStorageHint.setText(errorMessage); 423b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 424b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mStorageHint.show(); 425b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else if (mStorageHint != null) { 426b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mStorageHint.cancel(); 427b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mStorageHint = null; 428b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 429b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 430b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 4319a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project private int getStorageStatus(boolean mayHaveSd) { 4329a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project long remaining = mayHaveSd ? getAvailableStorage() : NO_STORAGE_ERROR; 4339a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project if (remaining == NO_STORAGE_ERROR) { 4349a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project return STORAGE_STATUS_NONE; 4359a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project } 4369a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project return remaining < LOW_STORAGE_THRESHOLD 4379a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project ? STORAGE_STATUS_LOW : STORAGE_STATUS_OK; 4389a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project } 4399a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project 440b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 441b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void onResume() { 442b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project super.onResume(); 443b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 444b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenTimeoutLong(); 445b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 446b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mPausing = false; 447b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 448b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // install an intent filter to receive SD card related events. 449b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MEDIA_MOUNTED); 450b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project intentFilter.addAction(Intent.ACTION_MEDIA_EJECT); 451b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project intentFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED); 452b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_STARTED); 453b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED); 454b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project intentFilter.addDataScheme("file"); 455b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project registerReceiver(mReceiver, intentFilter); 4569a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project mStorageStatus = getStorageStatus(true); 4579a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project 4589a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project mHandler.postDelayed(new Runnable() { 4599a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project public void run() { 4609a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project showStorageHint(); 4619a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project } 4629a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project }, 200); 463b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 4649bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang initializeVideo(); 465b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 466b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 467b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 468b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void onStop() { 469b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenTimeoutSystemDefault(); 470b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project super.onStop(); 471b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 472b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 473b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 474b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project protected void onPause() { 475b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project super.onPause(); 476b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 4779bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // This is similar to what mShutterButton.performClick() does, 4789bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // but not quite the same. 4799bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (mMediaRecorderRecording) { 4809bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (mIsVideoCaptureIntent) { 4819bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang stopVideoRecordingAndShowAlert(); 4829bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } else { 4839bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang stopVideoRecordingAndGetThumbnail(); 4849bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 4859bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } else { 4869bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang stopVideoRecording(); 4879bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 488b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 489b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mPausing = true; 490b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 4919c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project unregisterReceiver(mReceiver); 492b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenTimeoutSystemDefault(); 493b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 4949bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (!mIsVideoCaptureIntent) { 4959bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mThumbController.storeData(ImageManager.getLastVideoThumbPath()); 4969bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 497095afa19556bf550262e3cccb9edacc04e6f726aOwen Lin 498b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mStorageHint != null) { 499b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mStorageHint.cancel(); 500b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mStorageHint = null; 501b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 502b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 503b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 504b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 505b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public boolean onKeyDown(int keyCode, KeyEvent event) { 506b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenTimeoutLong(); 507b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 508b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project switch (keyCode) { 509b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case KeyEvent.KEYCODE_BACK: 510b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mMediaRecorderRecording) { 511de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mShutterButton.performClick(); 512b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 5139bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } else if(isAlertVisible()) { 5149bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang hideAlertAndStartPreview(); 515b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 516b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 517b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 518b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case KeyEvent.KEYCODE_CAMERA: 519b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (event.getRepeatCount() == 0) { 520de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mShutterButton.performClick(); 521b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 522b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 523de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project break; 524b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case KeyEvent.KEYCODE_DPAD_CENTER: 525b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (event.getRepeatCount() == 0) { 526de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mShutterButton.performClick(); 527de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project return true; 528b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 529b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 530b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case KeyEvent.KEYCODE_MENU: 531b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mMediaRecorderRecording) { 532de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mShutterButton.performClick(); 533b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 534b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 535b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 536b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 537b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 538b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return super.onKeyDown(keyCode, event); 539b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 540b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 541b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 542b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public boolean onKeyUp(int keyCode, KeyEvent event) { 543b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project switch(keyCode) { 544b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case KeyEvent.KEYCODE_CAMERA: 545b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mShutterButton.setPressed(false); 546b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 547b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 548b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return super.onKeyUp(keyCode, event); 549b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 550b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 551b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 552314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber if (mPausing) { 553314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber // We're pausing, the screen is off and we already stopped 554314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber // video recording. We don't want to start the camera again 555314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber // in this case in order to conserve power. 556314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber // The fact that surfaceChanged is called _after_ an onPause appears 557314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber // to be legitimate since in that case the lockscreen always returns 558314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber // to portrait orientation possibly triggering the notification. 559314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber return; 560314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber } 561314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber 562b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project stopVideoRecording(); 563b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project initializeVideo(); 564b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 565b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 566b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void surfaceCreated(SurfaceHolder holder) { 567b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mSurfaceHolder = holder; 568b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 569b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 570b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void surfaceDestroyed(SurfaceHolder holder) { 571b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mSurfaceHolder = null; 572b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 573b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 574b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project void gotoGallery() { 575b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project MenuHelper.gotoCameraVideoGallery(this); 576b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 577b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 578b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 579b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public boolean onPrepareOptionsMenu(Menu menu) { 580b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project super.onPrepareOptionsMenu(menu); 581b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 582b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project for (int i = 1; i <= MenuHelper.MENU_ITEM_MAX; i++) { 583b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (i != MenuHelper.GENERIC_ITEM) { 584b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project menu.setGroupVisible(i, false); 585b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 586b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 587b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 588b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project menu.setGroupVisible(MenuHelper.VIDEO_MODE_ITEM, true); 589b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 590b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 591b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 592b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 593b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public boolean onCreateOptionsMenu(Menu menu) { 594b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project super.onCreateOptionsMenu(menu); 595b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 5969bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (mIsVideoCaptureIntent) { 597b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // No options menu for attach mode. 598b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return false; 599b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 600b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project addBaseMenuItems(menu); 601095afa19556bf550262e3cccb9edacc04e6f726aOwen Lin int menuFlags = MenuHelper.INCLUDE_ALL & ~MenuHelper.INCLUDE_ROTATE_MENU 602095afa19556bf550262e3cccb9edacc04e6f726aOwen Lin & ~MenuHelper.INCLUDE_DETAILS_MENU; 603b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project MenuHelper.addImageMenuItems( 604b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project menu, 605095afa19556bf550262e3cccb9edacc04e6f726aOwen Lin menuFlags, 606b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project false, 607b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project VideoCamera.this, 608b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mHandler, 609b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 610b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // Handler for deletion 611b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project new Runnable() { 612b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void run() { 613b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // What do we do here? 614b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // mContentResolver.delete(uri, null, null); 615b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 616b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project }, 617b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project new MenuHelper.MenuInvoker() { 618b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void run(final MenuHelper.MenuCallback cb) { 619b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 620b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project }); 621b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 622b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project MenuItem gallery = menu.add(MenuHelper.IMAGE_SAVING_ITEM, MENU_SAVE_GALLERY_PHOTO, 0, 623b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project R.string.camera_gallery_photos_text).setOnMenuItemClickListener( 624b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project new MenuItem.OnMenuItemClickListener() { 625b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public boolean onMenuItemClick(MenuItem item) { 626b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project gotoGallery(); 627b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 628b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 629b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project }); 630b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project gallery.setIcon(android.R.drawable.ic_menu_gallery); 631b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 632b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 633b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 634b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 635b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private boolean isVideoCaptureIntent() { 636b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String action = getIntent().getAction(); 637b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return (MediaStore.ACTION_VIDEO_CAPTURE.equals(action)); 638b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 639b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 640b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void doReturnToCaller(boolean success) { 641b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Intent resultIntent = new Intent(); 642b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int resultCode; 643b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (success) { 644b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project resultCode = RESULT_OK; 645b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project resultIntent.setData(mCurrentVideoUri); 646b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 647b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project resultCode = RESULT_CANCELED; 648b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 649b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setResult(resultCode, resultIntent); 650b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project finish(); 651b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 652b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 653b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project /** 654b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * Returns 655b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * @return number of bytes available, or an ERROR code. 656b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project */ 657b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static long getAvailableStorage() { 658b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project try { 659b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (!ImageManager.hasStorage()) { 660b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return NO_STORAGE_ERROR; 661b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 662b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String storageDirectory = Environment.getExternalStorageDirectory().toString(); 663b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project StatFs stat = new StatFs(storageDirectory); 664b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return ((long)stat.getAvailableBlocks() * (long)stat.getBlockSize()); 665b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 666b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } catch (Exception ex) { 667b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // if we can't stat the filesystem then we don't know how many 668b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // free bytes exist. It might be zero but just leave it 669b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // blank since we really don't know. 670b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return CANNOT_STAT_ERROR; 671b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 672b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 673b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 674b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void cleanupEmptyFile() { 675b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mCameraVideoFilename != null) { 676b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project File f = new File(mCameraVideoFilename); 677b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (f.length() == 0 && f.delete()) { 678b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Empty video file deleted: " + mCameraVideoFilename); 679b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCameraVideoFilename = null; 680b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 681b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 682b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 683b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 6849bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // initializeVideo() starts preview and prepare media recorder. 685b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // Returns false if initializeVideo fails 686b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private boolean initializeVideo() { 687b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "initializeVideo"); 6889bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 6899bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // We will call initializeVideo() again when the alert is hidden. 6909bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (isAlertVisible()) return false; 6919bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 692b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Intent intent = getIntent(); 693b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Bundle myExtras = intent.getExtras(); 694b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 6959bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (mIsVideoCaptureIntent && myExtras != null) { 696b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Uri saveUri = (Uri) myExtras.getParcelable(MediaStore.EXTRA_OUTPUT); 697b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (saveUri != null) { 698b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project try { 699b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCameraVideoFileDescriptor = mContentResolver. 700b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project openFileDescriptor(saveUri, "rw").getFileDescriptor(); 701b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoUri = saveUri; 702b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 703b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project catch (java.io.FileNotFoundException ex) { 704b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // invalid uri 705b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.e(TAG, ex.toString()); 706b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 707b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 708b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 709b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project releaseMediaRecorder(); 710b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 711b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mSurfaceHolder == null) { 712b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "SurfaceHolder is null"); 713b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return false; 714b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 715b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 716b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder = new MediaRecorder(); 717b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 718b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (DEBUG_SUPPRESS_AUDIO_RECORDING) { 719b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "DEBUG_SUPPRESS_AUDIO_RECORDING is true."); 720b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 721b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); 722b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 723b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); 724b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); 725b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 7268d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project mMediaRecorder.setMaxDuration(MAX_RECORDING_DURATION_MS); 7278d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project 7289a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project if (mStorageStatus != STORAGE_STATUS_OK) { 729b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setOutputFile("/dev/null"); 730b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 731b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // We try Uri in intent first. If it doesn't work, use our own instead. 732b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mCameraVideoFileDescriptor != null) { 733b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setOutputFile(mCameraVideoFileDescriptor); 734b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 735b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project createVideoPath(); 736b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setOutputFile(mCameraVideoFilename); 737b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 738b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 739b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 740b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project boolean videoQualityHigh = getBooleanPreference(CameraSettings.KEY_VIDEO_QUALITY, 741b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project CameraSettings.DEFAULT_VIDEO_QUALITY_VALUE); 742b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 743b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (intent.hasExtra(MediaStore.EXTRA_VIDEO_QUALITY)) { 744b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int extraVideoQuality = intent.getIntExtra(MediaStore.EXTRA_VIDEO_QUALITY, 0); 745b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project videoQualityHigh = (extraVideoQuality > 0); 746b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 747b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 748b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // Use the same frame rate for both, since internally 749b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // if the frame rate is too large, it can cause camera to become 750b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // unstable. We need to fix the MediaRecorder to disable the support 751b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // of setting frame rate for now. 752b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setVideoFrameRate(20); 753b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (videoQualityHigh) { 754b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setVideoSize(352,288); 755b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 756b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setVideoSize(176,144); 757b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 758b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263); 759b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (!DEBUG_SUPPRESS_AUDIO_RECORDING) { 760b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); 761b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 762b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface()); 763de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 764de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project long remaining = getAvailableStorage(); 765de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project // remaining >= LOW_STORAGE_THRESHOLD at this point, reserve a quarter 766de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project // of that to make it more likely that recording can complete successfully. 767de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project try { 768de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mMediaRecorder.setMaxFileSize(remaining - LOW_STORAGE_THRESHOLD / 4); 769de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } catch (RuntimeException exception) { 770de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project // We are going to ignore failure of setMaxFileSize here, as 771de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project // a) The composer selected may simply not support it, or 772de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project // b) The underlying media framework may not handle 64-bit range 773de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project // on the size restriction. 774de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 775de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 776b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project try { 777b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.prepare(); 778b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } catch (IOException exception) { 779b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.e(TAG, "prepare failed for " + mCameraVideoFilename); 780b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project releaseMediaRecorder(); 781b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // TODO: add more exception handling logic here 782b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return false; 783b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 784b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorderRecording = false; 7859bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 7869bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (!mIsVideoCaptureIntent && !mThumbController.isUriValid()) { 7879bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang updateLastVideo(); 7889bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 7899bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 7909bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (!mIsVideoCaptureIntent) { 7919bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mThumbController.updateDisplayIfNeeded(); 7929bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 7939bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 794b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 795b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 796b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 797b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void releaseMediaRecorder() { 798b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Releasing media recorder."); 799b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mMediaRecorder != null) { 800b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project cleanupEmptyFile(); 801b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.reset(); 802b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.release(); 803b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder = null; 804b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 805b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 806b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 807b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private int getIntPreference(String key, int defaultValue) { 808b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String s = mPreferences.getString(key, ""); 809b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int result = defaultValue; 810b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project try { 811b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project result = Integer.parseInt(s); 812b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } catch (NumberFormatException e) { 813b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // Ignore, result is already the default value. 814b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 815b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return result; 816b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 817b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 818b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private boolean getBooleanPreference(String key, boolean defaultValue) { 819b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return getIntPreference(key, defaultValue ? 1 : 0) != 0; 820b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 821b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 822b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void createVideoPath() { 823b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project long dateTaken = System.currentTimeMillis(); 824b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String title = createName(dateTaken); 825b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String displayName = title + ".3gp"; // Used when emailing. 826b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String cameraDirPath = ImageManager.CAMERA_IMAGE_BUCKET_NAME; 827b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project File cameraDir = new File(cameraDirPath); 828b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project cameraDir.mkdirs(); 829b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project SimpleDateFormat dateFormat = new SimpleDateFormat( 830b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project getString(R.string.video_file_name_format)); 831b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Date date = new Date(dateTaken); 832b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String filepart = dateFormat.format(date); 833b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String filename = cameraDirPath + "/" + filepart + ".3gp"; 834b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project ContentValues values = new ContentValues(7); 835b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project values.put(Video.Media.TITLE, title); 836b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project values.put(Video.Media.DISPLAY_NAME, displayName); 837b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project values.put(Video.Media.DESCRIPTION, ""); 838b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project values.put(Video.Media.DATE_TAKEN, dateTaken); 839b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project values.put(Video.Media.MIME_TYPE, "video/3gpp"); 840b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project values.put(Video.Media.DATA, filename); 841b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCameraVideoFilename = filename; 842b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Current camera video filename: " + mCameraVideoFilename); 843b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoValues = values; 844b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 845b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 846b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void registerVideo() { 847b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mCameraVideoFileDescriptor == null) { 848b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Uri videoTable = Uri.parse("content://media/external/video/media"); 849b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoUri = mContentResolver.insert(videoTable, 850b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoValues); 851b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Current video URI: " + mCurrentVideoUri); 852b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 853b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoValues = null; 854b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 855b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 856b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void deleteCurrentVideo() { 857b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mCurrentVideoFilename != null) { 858b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project deleteVideoFile(mCurrentVideoFilename); 859b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoFilename = null; 860b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 861b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mCurrentVideoUri != null) { 862b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mContentResolver.delete(mCurrentVideoUri, null, null); 863b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoUri = null; 864b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 865de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project updateAndShowStorageHint(true); 866b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 867b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 868b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void deleteVideoFile(String fileName) { 869b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Deleting video " + fileName); 870b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project File f = new File(fileName); 871b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (! f.delete()) { 872b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Could not delete " + fileName); 873b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 874b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 875b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 876b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void addBaseMenuItems(Menu menu) { 877b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project MenuHelper.addSwitchModeMenuItem(menu, this, false); 878b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project { 879b64d345c9d51cabce43b5191532a0c185d2a70a5The 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() { 880b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public boolean onMenuItemClick(MenuItem item) { 881b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project gotoGallery(); 882b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 883b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 884b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project }); 885b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project gallery.setIcon(android.R.drawable.ic_menu_gallery); 886b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mGalleryItems.add(gallery); 887b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 888b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project { 889b64d345c9d51cabce43b5191532a0c185d2a70a5The 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() { 890b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public boolean onMenuItemClick(MenuItem item) { 891b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project gotoGallery(); 892b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 893b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 894b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project }); 895b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project gallery.setIcon(android.R.drawable.ic_menu_gallery); 896b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mGalleryItems.add(gallery); 897b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 898b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 899b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project MenuItem item = menu.add(MenuHelper.GENERIC_ITEM, MENU_SETTINGS, 0, R.string.settings).setOnMenuItemClickListener(new OnMenuItemClickListener() { 900b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public boolean onMenuItemClick(MenuItem item) { 901b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Intent intent = new Intent(); 902b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project intent.setClass(VideoCamera.this, CameraSettings.class); 903b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project startActivity(intent); 904b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 905b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 906b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project }); 907b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project item.setIcon(android.R.drawable.ic_menu_preferences); 908b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 909b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 910b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // from MediaRecorder.OnErrorListener 911b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void onError(MediaRecorder mr, int what, int extra) { 912b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (what == MediaRecorder.MEDIA_RECORDER_ERROR_UNKNOWN) { 913b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // We may have run out of space on the sdcard. 914b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project stopVideoRecording(); 9159a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project updateAndShowStorageHint(true); 916b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 917b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 918b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 9198d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project // from MediaRecorder.OnInfoListener 9208d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project public void onInfo(MediaRecorder mr, int what, int extra) { 9218d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) { 922de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mShutterButton.performClick(); 923de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } else if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED) { 924de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mShutterButton.performClick(); 925de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project updateAndShowStorageHint(true); 9268d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project } 9278d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project } 9288d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project 9299c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project /* 9309c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project * Make sure we're not recording music playing in the background, ask 9319c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project * the MediaPlaybackService to pause playback. 9329c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project */ 9339c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project private void pauseAudioPlayback() { 9349c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project // Shamelessly copied from MediaPlaybackService.java, which 9359c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project // should be public, but isn't. 9369c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project Intent i = new Intent("com.android.music.musicservicecommand"); 9379c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project i.putExtra("command", "pause"); 9389c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project 9399c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project sendBroadcast(i); 9409c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project } 9419c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project 942b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void startVideoRecording() { 943b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "startVideoRecording"); 944b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (!mMediaRecorderRecording) { 945b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 9469a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project if (mStorageStatus != STORAGE_STATUS_OK) { 947b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Storage issue, ignore the start request"); 948b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return; 949b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 950b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 951b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // Check mMediaRecorder to see whether it is initialized or not. 952b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mMediaRecorder == null && initializeVideo() == false ) { 953b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.e(TAG, "Initialize video (MediaRecorder) failed."); 954b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return; 955b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 956b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 9579c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project pauseAudioPlayback(); 9589c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project 959b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project try { 960b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setOnErrorListener(this); 9618d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project mMediaRecorder.setOnInfoListener(this); 962b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.start(); // Recording is now started 963b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } catch (RuntimeException e) { 964b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.e(TAG, "Could not start media recorder. ", e); 965b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return; 966b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 967b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorderRecording = true; 968b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mRecordingStartTime = SystemClock.uptimeMillis(); 969b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project updateRecordingIndicator(true); 970b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mRecordingTimeView.setText(""); 971b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mRecordingTimeView.setVisibility(View.VISIBLE); 972b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mHandler.sendEmptyMessage(UPDATE_RECORD_TIME); 973b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenTimeoutInfinite(); 974de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project hideLastPictureButton(); 975b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 976b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 977b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 978b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void updateRecordingIndicator(boolean showRecording) { 979b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int drawableId = showRecording ? R.drawable.ic_camera_bar_indicator_record 980b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project : R.drawable.ic_camera_indicator_video; 981b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Drawable drawable = getResources().getDrawable(drawableId); 982b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mShutterButton.setImageDrawable(drawable); 983b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 984b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 9859bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private void stopVideoRecordingAndGetThumbnail() { 9869bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang stopVideoRecording(); 9879bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang acquireVideoThumb(); 988b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 989b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 990de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project private void stopVideoRecordingAndShowAlert() { 991de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project stopVideoRecording(); 9929bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang showAlert(); 993de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 994de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 9959bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private void showAlert() { 996b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int[] pickIds = {R.id.attach, R.id.cancel}; 997b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int[] normalIds = {R.id.gallery, R.id.share, R.id.discard}; 998b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int[] alwaysOnIds = {R.id.play}; 999b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int[] hideIds = pickIds; 1000b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int[] connectIds = normalIds; 10019bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (mIsVideoCaptureIntent) { 1002b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project hideIds = normalIds; 1003b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project connectIds = pickIds; 1004b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1005b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project for(int id : hideIds) { 1006b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mPostPictureAlert.findViewById(id).setVisibility(View.GONE); 1007b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 10088d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project ActionMenuButton shareButton = 10098d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project (ActionMenuButton) mPostPictureAlert.findViewById(R.id.share); 10108d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project shareButton.setRestricted( 10118d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project mCurrentVideoFileLength > SHARE_FILE_LENGTH_LIMIT); 1012b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project connectAndFadeIn(connectIds); 1013b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project connectAndFadeIn(alwaysOnIds); 1014de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project hideLastPictureButton(); 1015b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mPostPictureAlert.setVisibility(View.VISIBLE); 10169bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 10179bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // There are two cases we are here: 10189bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // (1) We are in a capture video intent, and we are reviewing the video 1019095afa19556bf550262e3cccb9edacc04e6f726aOwen Lin // we just taken. 10209bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // (2) The thumbnail button is clicked: we review the video associated 10219bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // with the thumbnail. 10229bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // For the second case, we copy the associated URI and filename to 10239bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // mCurrentVideoUri and mCurrentVideoFilename, so the video frame shown 10249bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // and the target for actions (play, delete, ...) will be correct. 10259bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 10269bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (!mIsVideoCaptureIntent) { 10279bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mCurrentVideoUri = mThumbController.getUri(); 10289bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mCurrentVideoFilename = getDataPath(mCurrentVideoUri); 10299bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 10309bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 10319bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang String path = mCurrentVideoFilename; 10329bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (path != null) { 1033101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin Bitmap videoFrame = Util.createVideoThumbnail(path); 10349bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mVideoFrame.setImageBitmap(videoFrame); 10359bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mVideoFrame.setVisibility(View.VISIBLE); 10369bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 1037b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1038b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 10399bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private void hideAlert() { 1040de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mVideoFrame.setVisibility(View.INVISIBLE); 1041de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mPostPictureAlert.setVisibility(View.INVISIBLE); 1042de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project showLastPictureButton(); 1043de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 1044de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 1045b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void connectAndFadeIn(int[] connectIds) { 1046b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project for(int id : connectIds) { 1047b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project View view = mPostPictureAlert.findViewById(id); 1048b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project view.setOnClickListener(this); 1049b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Animation animation = new AlphaAnimation(0F, 1F); 1050b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project animation.setDuration(500); 10519bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang view.startAnimation(animation); 1052b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1053b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1054b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 10559bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private boolean isAlertVisible() { 1056b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return mPostPictureAlert.getVisibility() == View.VISIBLE; 1057b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1058b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1059b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void stopVideoRecording() { 1060b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "stopVideoRecording"); 1061b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project boolean needToRegisterRecording = false; 1062b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mMediaRecorderRecording || mMediaRecorder != null) { 1063b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mMediaRecorderRecording && mMediaRecorder != null) { 1064b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project try { 1065b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setOnErrorListener(null); 10668d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project mMediaRecorder.setOnInfoListener(null); 1067b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.stop(); 1068b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } catch (RuntimeException e) { 1069b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.e(TAG, "stop fail: " + e.getMessage()); 1070b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 10718d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project 1072b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoFilename = mCameraVideoFilename; 10738d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project try { 10748d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project mCurrentVideoFileLength = new File(mCurrentVideoFilename).length(); 10758d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project } catch (RuntimeException e) { 10768d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project Log.e(TAG, "get file length fail: " + e.getMessage()); 10778d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project mCurrentVideoFileLength = 0; 10788d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project } 1079b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Setting current video filename: " + mCurrentVideoFilename); 1080b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project needToRegisterRecording = true; 1081b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorderRecording = false; 1082b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1083b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project releaseMediaRecorder(); 1084b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project updateRecordingIndicator(false); 1085b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mRecordingTimeView.setVisibility(View.GONE); 1086b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenTimeoutLong(); 1087b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 10889a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project if (needToRegisterRecording && mStorageStatus == STORAGE_STATUS_OK) { 10899a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project registerVideo(); 10909a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project } 1091b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1092b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCameraVideoFilename = null; 1093b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCameraVideoFileDescriptor = null; 1094b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1095b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1096b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void setScreenTimeoutSystemDefault() { 1097b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mHandler.removeMessages(CLEAR_SCREEN_DELAY); 1098b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project clearScreenOnFlag(); 1099b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1100b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1101b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void setScreenTimeoutLong() { 1102b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mHandler.removeMessages(CLEAR_SCREEN_DELAY); 1103b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenOnFlag(); 1104b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mHandler.sendEmptyMessageDelayed(CLEAR_SCREEN_DELAY, SCREEN_DELAY); 1105b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1106b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1107b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void setScreenTimeoutInfinite() { 1108b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mHandler.removeMessages(CLEAR_SCREEN_DELAY); 1109b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenOnFlag(); 1110b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1111b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1112b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void clearScreenOnFlag() { 1113b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Window w = getWindow(); 1114b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project final int keepScreenOnFlag = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; 1115b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if ((w.getAttributes().flags & keepScreenOnFlag) != 0) { 1116b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project w.clearFlags(keepScreenOnFlag); 1117b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1118b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1119b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1120b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void setScreenOnFlag() { 1121b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Window w = getWindow(); 1122b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project final int keepScreenOnFlag = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; 1123b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if ((w.getAttributes().flags & keepScreenOnFlag) == 0) { 1124b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project w.addFlags(keepScreenOnFlag); 1125b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1126b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1127b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 11289bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private void hideAlertAndStartPreview() { 11299bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang hideAlert(); 11309bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang initializeVideo(); 1131b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1132b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 11339bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private void hideAlertAndStartVideoRecording() { 11349bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang hideAlert(); 11359bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang startVideoRecording(); 1136b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1137b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 11389bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private void acquireVideoThumb() { 1139101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin Bitmap videoFrame = Util.createVideoThumbnail(mCurrentVideoFilename); 11409bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mThumbController.setData(mCurrentVideoUri, videoFrame); 1141de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 1142de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 11439bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private void showLastPictureButton() { 11449bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (!mIsVideoCaptureIntent) { 11459bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mLastPictureButton.setVisibility(View.VISIBLE); 1146de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 11479bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 1148de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 11499bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private void hideLastPictureButton() { 11509bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (!mIsVideoCaptureIntent) { 11519bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mLastPictureButton.setVisibility(View.INVISIBLE); 11529bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 1153de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 1154de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 11559bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private static ImageManager.DataLocation dataLocation() { 11569bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang return ImageManager.DataLocation.EXTERNAL; 1157de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 1158de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 11599bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private void updateLastVideo() { 1160101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin IImageList list = ImageManager.instance().allImages( 11619bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang this, 11629bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mContentResolver, 11639bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang dataLocation(), 11649bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang ImageManager.INCLUDE_VIDEOS, 11659bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang ImageManager.SORT_ASCENDING, 11669bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang ImageManager.CAMERA_IMAGE_BUCKET_ID); 11679bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang int count = list.getCount(); 11689bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (count > 0) { 1169101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin IImage image = list.getImageAt(count-1); 11709bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang Uri uri = image.fullSizeImageUri(); 11719bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mThumbController.setData(uri, image.miniThumbBitmap()); 11729bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } else { 11739bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mThumbController.setData(null, null); 11749bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 11759bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang list.deactivate(); 1176b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1177b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 11789bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private static final String[] DATA_PATH_PROJECTION = new String[] { 11799bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang "_data" 11809bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang }; 11819bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 11829bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private String getDataPath(Uri uri) { 11839bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang Cursor c = null; 11849bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang try { 11859bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang c = mContentResolver.query(uri, DATA_PATH_PROJECTION, null, null, null); 11869bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (c != null && c.moveToFirst()) { 11879bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang return c.getString(0); 11889bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } else { 11899bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang return null; 11909bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 11919bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } finally { 11929bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (c != null) c.close(); 1193b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1194b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1195b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project} 1196