VideoCamera.java revision 937fc48b37fafe3ffc8f4b52bd9a171bbb4d3a37
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 Lin 22b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.app.Activity; 23b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.BroadcastReceiver; 24b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.ContentResolver; 25b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.ContentValues; 26b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.Context; 27b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.Intent; 28b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.IntentFilter; 29b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.SharedPreferences; 30095afa19556bf550262e3cccb9edacc04e6f726aOwen Linimport android.database.Cursor; 31b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.graphics.Bitmap; 32b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.graphics.drawable.Drawable; 33b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.location.LocationManager; 34b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.media.MediaRecorder; 35b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.net.Uri; 36b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.Bundle; 37b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.Environment; 38b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.Handler; 39b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.Message; 40b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.StatFs; 41b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.SystemClock; 42b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.preference.PreferenceManager; 43b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.provider.MediaStore; 44b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.provider.MediaStore.Video; 45b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.text.format.DateFormat; 46b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.util.Log; 47b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.KeyEvent; 48b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.Menu; 49b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.MenuItem; 50b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.SurfaceHolder; 51b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.View; 52b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.Window; 53b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.WindowManager; 54937fc48b37fafe3ffc8f4b52bd9a171bbb4d3a37Owen Linimport android.view.MenuItem.OnMenuItemClickListener; 55b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.animation.AlphaAnimation; 56b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.animation.Animation; 57b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.widget.ImageView; 58b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.widget.TextView; 59b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.widget.Toast; 60b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 61d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Changimport java.io.File; 62d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Changimport java.io.FileDescriptor; 63d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Changimport java.io.IOException; 64d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Changimport java.text.SimpleDateFormat; 65d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Changimport java.util.ArrayList; 66d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Changimport java.util.Date; 67d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang 6823c51b794e95c201290e36737f379c4bb8eefeaeRay Chen/** 6923c51b794e95c201290e36737f379c4bb8eefeaeRay Chen * The Camcorder activity. 7023c51b794e95c201290e36737f379c4bb8eefeaeRay Chen */ 71b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectpublic class VideoCamera extends Activity implements View.OnClickListener, 72d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang ShutterButton.OnShutterButtonListener, SurfaceHolder.Callback, 73d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang MediaRecorder.OnErrorListener, MediaRecorder.OnInfoListener { 74b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 75b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final String TAG = "videocamera"; 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 133d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang private 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 148d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // This Handler is used to post message back onto the main thread of the 149d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // application 150b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private class MainHandler extends Handler { 151b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 152b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void handleMessage(Message msg) { 153b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project switch (msg.what) { 154b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 155b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case CLEAR_SCREEN_DELAY: { 156b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project clearScreenOnFlag(); 157b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 158b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 159b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 160b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case UPDATE_RECORD_TIME: { 161d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang updateRecordingTime(); 162b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 163b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 164b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 165b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project default: 166b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Unhandled message: " + msg.what); 167b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 168b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 169b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 170937fc48b37fafe3ffc8f4b52bd9a171bbb4d3a37Owen Lin } 171b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 172b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 173b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 174b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void onReceive(Context context, Intent intent) { 175b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String action = intent.getAction(); 176b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (action.equals(Intent.ACTION_MEDIA_EJECT)) { 1779a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project updateAndShowStorageHint(false); 178b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project stopVideoRecording(); 179b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project initializeVideo(); 180b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else if (action.equals(Intent.ACTION_MEDIA_MOUNTED)) { 1819a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project updateAndShowStorageHint(true); 182b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project initializeVideo(); 183b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else if (action.equals(Intent.ACTION_MEDIA_UNMOUNTED)) { 184b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // SD card unavailable 1859a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project // handled in ACTION_MEDIA_EJECT 186b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else if (action.equals(Intent.ACTION_MEDIA_SCANNER_STARTED)) { 187d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang Toast.makeText(VideoCamera.this, 188d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang getResources().getString(R.string.wait), 5000); 189b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else if (action.equals(Intent.ACTION_MEDIA_SCANNER_FINISHED)) { 1909a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project updateAndShowStorageHint(true); 191b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 192b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 193b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project }; 194b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 195d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang private static String createName(long dateTaken) { 196b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return DateFormat.format("yyyy-MM-dd kk.mm.ss", dateTaken).toString(); 197b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 198b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 199b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project /** Called with the activity is first created. */ 200b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 201b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void onCreate(Bundle icicle) { 202b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project super.onCreate(icicle); 203b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 204d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang mLocationManager = (LocationManager) getSystemService( 205d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang Context.LOCATION_SERVICE); 206b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 207b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mPreferences = PreferenceManager.getDefaultSharedPreferences(this); 208b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mContentResolver = getContentResolver(); 209b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 210b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project //setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT); 211b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project requestWindowFeature(Window.FEATURE_PROGRESS); 212b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setContentView(R.layout.video_camera); 213b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 214b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mVideoPreview = (VideoPreview) findViewById(R.id.camera_preview); 215b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mVideoPreview.setAspectRatio(VIDEO_ASPECT_RATIO); 216b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 217b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // don't set mSurfaceHolder here. We have it set ONLY within 218b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // surfaceCreated / surfaceDestroyed, other parts of the code 219b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // assume that when it is set, the surface is also set. 220b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project SurfaceHolder holder = mVideoPreview.getHolder(); 221b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project holder.addCallback(this); 222b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 223b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 224b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mPostPictureAlert = findViewById(R.id.post_picture_panel); 225b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 226b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int[] ids = new int[]{R.id.play, R.id.share, R.id.discard, 227b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project R.id.cancel, R.id.attach}; 228b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project for (int id : ids) { 229b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project findViewById(id).setOnClickListener(this); 230b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 231b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 232b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mShutterButton = (ShutterButton) findViewById(R.id.shutter_button); 233b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mShutterButton.setOnShutterButtonListener(this); 234b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mRecordingTimeView = (TextView) findViewById(R.id.recording_time); 235b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mVideoFrame = (ImageView) findViewById(R.id.video_frame); 2369bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mIsVideoCaptureIntent = isVideoCaptureIntent(); 2379bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (!mIsVideoCaptureIntent) { 238d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang mLastPictureButton = (ImageView) findViewById( 239d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang R.id.last_picture_button); 2409bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mLastPictureButton.setOnClickListener(this); 241d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang Drawable frame = getResources().getDrawable( 242d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang R.drawable.frame_thumbnail); 2439bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mThumbController = new ThumbnailController(mLastPictureButton, 2449bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang frame, mContentResolver); 2459bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mThumbController.loadData(ImageManager.getLastVideoThumbPath()); 2469bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 247b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 248b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 249e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project private void startShareVideoActivity() { 2508d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project if (mCurrentVideoFileLength > SHARE_FILE_LENGTH_LIMIT) { 251e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project Toast.makeText(VideoCamera.this, 252e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project R.string.too_large_to_attach, Toast.LENGTH_LONG).show(); 253e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project return; 254e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project } 255e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project Intent intent = new Intent(); 256e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project intent.setAction(Intent.ACTION_SEND); 257e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project intent.setType("video/3gpp"); 258e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project intent.putExtra(Intent.EXTRA_STREAM, mCurrentVideoUri); 259e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project try { 260d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang startActivity(Intent.createChooser( 261d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang intent, getText(R.string.sendVideo))); 262e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project } catch (android.content.ActivityNotFoundException ex) { 263d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang Toast.makeText(VideoCamera.this, R.string.no_way_to_share_video, 264d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang Toast.LENGTH_SHORT).show(); 265e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project } 266e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project } 267e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project 268b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void onClick(View v) { 269b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project switch (v.getId()) { 270b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 271b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case R.id.gallery: 272b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project MenuHelper.gotoCameraVideoGallery(this); 273b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 274b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 275b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case R.id.attach: 276b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project doReturnToCaller(true); 277b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 278b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 279b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case R.id.cancel: 280b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project doReturnToCaller(false); 281b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 282b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 283b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case R.id.discard: { 2847638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen Runnable deleteCallback = new Runnable() { 2857638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen public void run() { 2867638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen discardCurrentVideoAndStartPreview(); 2877638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen } 2887638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen }; 2897638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen MenuHelper.deleteVideo(this, deleteCallback); 290b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 291b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 292b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 293b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case R.id.share: { 294e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project startShareVideoActivity(); 295b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 296b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 297b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 298b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case R.id.play: { 299b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project doPlayCurrentVideo(); 300b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 301b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 302de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 303de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project case R.id.last_picture_button: { 3049bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang stopVideoRecordingAndShowAlert(); 305de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project break; 306de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 307b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 308b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 309b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 310b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void onShutterButtonFocus(ShutterButton button, boolean pressed) { 311de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project // Do nothing (everything happens in onShutterButtonClick). 312de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 313de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 314de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project public void onShutterButtonClick(ShutterButton button) { 315b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project switch (button.getId()) { 316b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case R.id.shutter_button: 317de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project if (mMediaRecorderRecording) { 3189bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (mIsVideoCaptureIntent) { 319de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project stopVideoRecordingAndShowAlert(); 320b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 3219bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang stopVideoRecordingAndGetThumbnail(); 3229bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang initializeVideo(); 3239bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 3249bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } else if (isAlertVisible()) { 3259bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (mIsVideoCaptureIntent) { 3269bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang discardCurrentVideoAndStartPreview(); 3279bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } else { 3289bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang hideAlertAndStartVideoRecording(); 329b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 330de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } else { 331de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project startVideoRecording(); 332b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 333b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 334b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 335b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 336b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 337b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void doPlayCurrentVideo() { 338b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.e(TAG, "Playing current video: " + mCurrentVideoUri); 339b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Intent intent = new Intent(Intent.ACTION_VIEW, mCurrentVideoUri); 340b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project try { 341b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project startActivity(intent); 342b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } catch (android.content.ActivityNotFoundException ex) { 343b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.e(TAG, "Couldn't view video " + mCurrentVideoUri, ex); 344b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 345b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 346b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 347b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void discardCurrentVideoAndStartPreview() { 348b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project deleteCurrentVideo(); 3499bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang hideAlertAndStartPreview(); 350b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 351b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 352b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private OnScreenHint mStorageHint; 353b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 3549a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project private void updateAndShowStorageHint(boolean mayHaveSd) { 3559a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project mStorageStatus = getStorageStatus(mayHaveSd); 3569a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project showStorageHint(); 3579a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project } 3589a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project 3599a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project private void showStorageHint() { 360b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String errorMessage = null; 3619a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project switch (mStorageStatus) { 3629a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project case STORAGE_STATUS_NONE: 363b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project errorMessage = getString(R.string.no_storage); 3649a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project break; 3659a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project case STORAGE_STATUS_LOW: 366b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project errorMessage = getString(R.string.spaceIsLow_content); 367b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 368b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (errorMessage != null) { 369b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mStorageHint == null) { 370b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mStorageHint = OnScreenHint.makeText(this, errorMessage); 371b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 372b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mStorageHint.setText(errorMessage); 373b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 374b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mStorageHint.show(); 375b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else if (mStorageHint != null) { 376b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mStorageHint.cancel(); 377b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mStorageHint = null; 378b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 379b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 380b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 3819a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project private int getStorageStatus(boolean mayHaveSd) { 3829a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project long remaining = mayHaveSd ? getAvailableStorage() : NO_STORAGE_ERROR; 3839a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project if (remaining == NO_STORAGE_ERROR) { 3849a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project return STORAGE_STATUS_NONE; 3859a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project } 3869a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project return remaining < LOW_STORAGE_THRESHOLD 3879a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project ? STORAGE_STATUS_LOW : STORAGE_STATUS_OK; 3889a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project } 3899a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project 390b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 391b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void onResume() { 392b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project super.onResume(); 393b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 394b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenTimeoutLong(); 395b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 396b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mPausing = false; 397b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 398b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // install an intent filter to receive SD card related events. 399d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang IntentFilter intentFilter = 400d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang new IntentFilter(Intent.ACTION_MEDIA_MOUNTED); 401b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project intentFilter.addAction(Intent.ACTION_MEDIA_EJECT); 402b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project intentFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED); 403b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_STARTED); 404b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED); 405b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project intentFilter.addDataScheme("file"); 406b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project registerReceiver(mReceiver, intentFilter); 4079a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project mStorageStatus = getStorageStatus(true); 4089a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project 4099a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project mHandler.postDelayed(new Runnable() { 4109a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project public void run() { 4119a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project showStorageHint(); 4129a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project } 4139a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project }, 200); 414b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 4159bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang initializeVideo(); 416b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 417b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 418b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 419b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void onStop() { 420b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenTimeoutSystemDefault(); 421b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project super.onStop(); 422b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 423b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 424b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 425b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project protected void onPause() { 426b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project super.onPause(); 427b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 4289bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // This is similar to what mShutterButton.performClick() does, 4299bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // but not quite the same. 4309bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (mMediaRecorderRecording) { 4319bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (mIsVideoCaptureIntent) { 4329bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang stopVideoRecordingAndShowAlert(); 4339bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } else { 4349bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang stopVideoRecordingAndGetThumbnail(); 4359bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 4369bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } else { 4379bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang stopVideoRecording(); 4389bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 439b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 440b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mPausing = true; 441b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 4429c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project unregisterReceiver(mReceiver); 443b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenTimeoutSystemDefault(); 444b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 4459bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (!mIsVideoCaptureIntent) { 4469bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mThumbController.storeData(ImageManager.getLastVideoThumbPath()); 4479bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 448095afa19556bf550262e3cccb9edacc04e6f726aOwen Lin 449b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mStorageHint != null) { 450b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mStorageHint.cancel(); 451b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mStorageHint = null; 452b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 453b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 454b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 455b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 456b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public boolean onKeyDown(int keyCode, KeyEvent event) { 457b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenTimeoutLong(); 458b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 459b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project switch (keyCode) { 460b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case KeyEvent.KEYCODE_BACK: 461b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mMediaRecorderRecording) { 462de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mShutterButton.performClick(); 463b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 464d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang } else if (isAlertVisible()) { 4659bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang hideAlertAndStartPreview(); 466b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 467b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 468b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 469b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case KeyEvent.KEYCODE_CAMERA: 470b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (event.getRepeatCount() == 0) { 471de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mShutterButton.performClick(); 472b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 473b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 474de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project break; 475b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case KeyEvent.KEYCODE_DPAD_CENTER: 476b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (event.getRepeatCount() == 0) { 477de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mShutterButton.performClick(); 478de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project return true; 479b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 480b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 481b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case KeyEvent.KEYCODE_MENU: 482b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mMediaRecorderRecording) { 483de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mShutterButton.performClick(); 484b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 485b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 486b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 487b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 488b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 489b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return super.onKeyDown(keyCode, event); 490b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 491b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 492b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 493b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public boolean onKeyUp(int keyCode, KeyEvent event) { 494b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project switch(keyCode) { 495b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case KeyEvent.KEYCODE_CAMERA: 496b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mShutterButton.setPressed(false); 497b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 498b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 499b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return super.onKeyUp(keyCode, event); 500b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 501b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 502b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 503314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber if (mPausing) { 504314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber // We're pausing, the screen is off and we already stopped 505314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber // video recording. We don't want to start the camera again 506314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber // in this case in order to conserve power. 507314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber // The fact that surfaceChanged is called _after_ an onPause appears 508314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber // to be legitimate since in that case the lockscreen always returns 509314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber // to portrait orientation possibly triggering the notification. 510314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber return; 511314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber } 512314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber 513b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project stopVideoRecording(); 514b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project initializeVideo(); 515b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 516b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 517b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void surfaceCreated(SurfaceHolder holder) { 518b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mSurfaceHolder = holder; 519b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 520b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 521b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void surfaceDestroyed(SurfaceHolder holder) { 522b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mSurfaceHolder = null; 523b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 524b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 525b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project void gotoGallery() { 526b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project MenuHelper.gotoCameraVideoGallery(this); 527b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 528b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 529b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 530b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public boolean onPrepareOptionsMenu(Menu menu) { 531b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project super.onPrepareOptionsMenu(menu); 532b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 533b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project for (int i = 1; i <= MenuHelper.MENU_ITEM_MAX; i++) { 534b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (i != MenuHelper.GENERIC_ITEM) { 535b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project menu.setGroupVisible(i, false); 536b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 537b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 538b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 539b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project menu.setGroupVisible(MenuHelper.VIDEO_MODE_ITEM, true); 540b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 541b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 542b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 543b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 544b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public boolean onCreateOptionsMenu(Menu menu) { 545b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project super.onCreateOptionsMenu(menu); 546b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 5479bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (mIsVideoCaptureIntent) { 548b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // No options menu for attach mode. 549b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return false; 550b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 551b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project addBaseMenuItems(menu); 552d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang int menuFlags = MenuHelper.INCLUDE_ALL 553d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang & ~MenuHelper.INCLUDE_ROTATE_MENU 554095afa19556bf550262e3cccb9edacc04e6f726aOwen Lin & ~MenuHelper.INCLUDE_DETAILS_MENU; 555b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project MenuHelper.addImageMenuItems( 556b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project menu, 557095afa19556bf550262e3cccb9edacc04e6f726aOwen Lin menuFlags, 558b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project false, 559b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project VideoCamera.this, 56023c51b794e95c201290e36737f379c4bb8eefeaeRay Chen mHandler, 561b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // Handler for deletion 562b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project new Runnable() { 563b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void run() { 564b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // What do we do here? 565b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // mContentResolver.delete(uri, null, null); 566b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 567b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project }, 568b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project new MenuHelper.MenuInvoker() { 569b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void run(final MenuHelper.MenuCallback cb) { 570b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 571b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project }); 572b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 573d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang MenuItem gallery = menu.add(MenuHelper.IMAGE_SAVING_ITEM, 574d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang MENU_SAVE_GALLERY_PHOTO, 0, 575d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang R.string.camera_gallery_photos_text) 576d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang .setOnMenuItemClickListener( 577d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang new MenuItem.OnMenuItemClickListener() { 578d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang public boolean onMenuItemClick(MenuItem item) { 579d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang gotoGallery(); 580d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang return true; 581d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang } 582d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang }); 583b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project gallery.setIcon(android.R.drawable.ic_menu_gallery); 584b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 585b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 586b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 587b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 588b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private boolean isVideoCaptureIntent() { 589b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String action = getIntent().getAction(); 590b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return (MediaStore.ACTION_VIDEO_CAPTURE.equals(action)); 591b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 592b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 593b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void doReturnToCaller(boolean success) { 594b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Intent resultIntent = new Intent(); 595b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int resultCode; 596b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (success) { 597b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project resultCode = RESULT_OK; 598b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project resultIntent.setData(mCurrentVideoUri); 599b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 600b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project resultCode = RESULT_CANCELED; 601b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 602b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setResult(resultCode, resultIntent); 603b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project finish(); 604b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 605b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 606b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project /** 607b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * Returns 608b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * @return number of bytes available, or an ERROR code. 609b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project */ 610b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static long getAvailableStorage() { 611b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project try { 612b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (!ImageManager.hasStorage()) { 613b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return NO_STORAGE_ERROR; 614b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 615d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang String storageDirectory = Environment 616d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang .getExternalStorageDirectory().toString(); 617b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project StatFs stat = new StatFs(storageDirectory); 618d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang return ((long) stat.getAvailableBlocks() 619d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang * (long) stat.getBlockSize()); 620b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 62123c51b794e95c201290e36737f379c4bb8eefeaeRay Chen } catch (RuntimeException ex) { 622b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // if we can't stat the filesystem then we don't know how many 623b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // free bytes exist. It might be zero but just leave it 624b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // blank since we really don't know. 625b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return CANNOT_STAT_ERROR; 626b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 627b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 628b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 629b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void cleanupEmptyFile() { 630b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mCameraVideoFilename != null) { 631b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project File f = new File(mCameraVideoFilename); 632b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (f.length() == 0 && f.delete()) { 633b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Empty video file deleted: " + mCameraVideoFilename); 634b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCameraVideoFilename = null; 635b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 636b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 637b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 638b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 6399bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // initializeVideo() starts preview and prepare media recorder. 640b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // Returns false if initializeVideo fails 641b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private boolean initializeVideo() { 642b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "initializeVideo"); 6439bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 6449bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // We will call initializeVideo() again when the alert is hidden. 64523c51b794e95c201290e36737f379c4bb8eefeaeRay Chen if (isAlertVisible()) { 64623c51b794e95c201290e36737f379c4bb8eefeaeRay Chen return false; 64723c51b794e95c201290e36737f379c4bb8eefeaeRay Chen } 6489bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 649b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Intent intent = getIntent(); 650b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Bundle myExtras = intent.getExtras(); 651b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 6529bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (mIsVideoCaptureIntent && myExtras != null) { 653b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Uri saveUri = (Uri) myExtras.getParcelable(MediaStore.EXTRA_OUTPUT); 654b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (saveUri != null) { 655b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project try { 656b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCameraVideoFileDescriptor = mContentResolver. 657b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project openFileDescriptor(saveUri, "rw").getFileDescriptor(); 658b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoUri = saveUri; 659d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang } catch (java.io.FileNotFoundException ex) { 660b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // invalid uri 661b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.e(TAG, ex.toString()); 662b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 663b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 664b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 665b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project releaseMediaRecorder(); 666b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 667b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mSurfaceHolder == null) { 668b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "SurfaceHolder is null"); 669b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return false; 670b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 671b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 672b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder = new MediaRecorder(); 673b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 674d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); 675b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); 676b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); 677b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 6788d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project mMediaRecorder.setMaxDuration(MAX_RECORDING_DURATION_MS); 6798d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project 6809a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project if (mStorageStatus != STORAGE_STATUS_OK) { 681b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setOutputFile("/dev/null"); 682b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 683d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // We try Uri in intent first. If it doesn't work, use our own 684d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // instead. 685b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mCameraVideoFileDescriptor != null) { 686b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setOutputFile(mCameraVideoFileDescriptor); 687b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 688b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project createVideoPath(); 689b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setOutputFile(mCameraVideoFilename); 690b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 691b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 692b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 693d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang boolean videoQualityHigh = getBooleanPreference( 694d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang CameraSettings.KEY_VIDEO_QUALITY, 695b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project CameraSettings.DEFAULT_VIDEO_QUALITY_VALUE); 696b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 697b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (intent.hasExtra(MediaStore.EXTRA_VIDEO_QUALITY)) { 698d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang int extraVideoQuality = intent.getIntExtra( 699d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang MediaStore.EXTRA_VIDEO_QUALITY, 0); 700b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project videoQualityHigh = (extraVideoQuality > 0); 701b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 702b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 703b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // Use the same frame rate for both, since internally 704b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // if the frame rate is too large, it can cause camera to become 705b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // unstable. We need to fix the MediaRecorder to disable the support 706b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // of setting frame rate for now. 707b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setVideoFrameRate(20); 708b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (videoQualityHigh) { 709d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang mMediaRecorder.setVideoSize(352, 288); 710b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 711d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang mMediaRecorder.setVideoSize(176, 144); 712b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 713b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263); 714d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); 715b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface()); 716de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 717de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project long remaining = getAvailableStorage(); 718de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project // remaining >= LOW_STORAGE_THRESHOLD at this point, reserve a quarter 719d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // of that to make it more likely that recording can complete 720d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // successfully. 721de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project try { 722d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang mMediaRecorder.setMaxFileSize(remaining - 723d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang LOW_STORAGE_THRESHOLD / 4); 724de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } catch (RuntimeException exception) { 725de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project // We are going to ignore failure of setMaxFileSize here, as 726de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project // a) The composer selected may simply not support it, or 727de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project // b) The underlying media framework may not handle 64-bit range 728de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project // on the size restriction. 729de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 730de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 731b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project try { 732b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.prepare(); 733b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } catch (IOException exception) { 734b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.e(TAG, "prepare failed for " + mCameraVideoFilename); 735b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project releaseMediaRecorder(); 736b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // TODO: add more exception handling logic here 737b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return false; 738b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 739b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorderRecording = false; 7409bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 7419bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (!mIsVideoCaptureIntent && !mThumbController.isUriValid()) { 7429bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang updateLastVideo(); 7439bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 7449bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 7459bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (!mIsVideoCaptureIntent) { 7469bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mThumbController.updateDisplayIfNeeded(); 7479bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 7489bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 749b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 750b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 751b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 752b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void releaseMediaRecorder() { 753b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Releasing media recorder."); 754b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mMediaRecorder != null) { 755b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project cleanupEmptyFile(); 756b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.reset(); 757b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.release(); 758b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder = null; 759b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 760b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 761b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 762b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private int getIntPreference(String key, int defaultValue) { 763b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String s = mPreferences.getString(key, ""); 764b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int result = defaultValue; 765b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project try { 766b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project result = Integer.parseInt(s); 767b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } catch (NumberFormatException e) { 768b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // Ignore, result is already the default value. 769b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 770b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return result; 771b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 772b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 773b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private boolean getBooleanPreference(String key, boolean defaultValue) { 774b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return getIntPreference(key, defaultValue ? 1 : 0) != 0; 775b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 776b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 777b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void createVideoPath() { 778b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project long dateTaken = System.currentTimeMillis(); 779b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String title = createName(dateTaken); 780b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String displayName = title + ".3gp"; // Used when emailing. 781b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String cameraDirPath = ImageManager.CAMERA_IMAGE_BUCKET_NAME; 782b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project File cameraDir = new File(cameraDirPath); 783b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project cameraDir.mkdirs(); 784b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project SimpleDateFormat dateFormat = new SimpleDateFormat( 785b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project getString(R.string.video_file_name_format)); 786b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Date date = new Date(dateTaken); 787b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String filepart = dateFormat.format(date); 788b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String filename = cameraDirPath + "/" + filepart + ".3gp"; 789b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project ContentValues values = new ContentValues(7); 790b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project values.put(Video.Media.TITLE, title); 791b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project values.put(Video.Media.DISPLAY_NAME, displayName); 792b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project values.put(Video.Media.DATE_TAKEN, dateTaken); 793b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project values.put(Video.Media.MIME_TYPE, "video/3gpp"); 794b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project values.put(Video.Media.DATA, filename); 795b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCameraVideoFilename = filename; 796b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Current camera video filename: " + mCameraVideoFilename); 797b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoValues = values; 798b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 799b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 800b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void registerVideo() { 801b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mCameraVideoFileDescriptor == null) { 802b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Uri videoTable = Uri.parse("content://media/external/video/media"); 803b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoUri = mContentResolver.insert(videoTable, 804b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoValues); 805b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Current video URI: " + mCurrentVideoUri); 806b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 807b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoValues = null; 808b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 809b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 810b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void deleteCurrentVideo() { 811b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mCurrentVideoFilename != null) { 812b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project deleteVideoFile(mCurrentVideoFilename); 813b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoFilename = null; 814b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 815b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mCurrentVideoUri != null) { 816b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mContentResolver.delete(mCurrentVideoUri, null, null); 817b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoUri = null; 818b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 819de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project updateAndShowStorageHint(true); 820b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 821b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 822b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void deleteVideoFile(String fileName) { 823b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Deleting video " + fileName); 824b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project File f = new File(fileName); 825d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang if (!f.delete()) { 826b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Could not delete " + fileName); 827b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 828b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 829b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 830b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void addBaseMenuItems(Menu menu) { 831b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project MenuHelper.addSwitchModeMenuItem(menu, this, false); 832b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project { 833d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang MenuItem gallery = menu.add(MenuHelper.IMAGE_MODE_ITEM, 834d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang MENU_GALLERY_PHOTOS, 0, R.string.camera_gallery_photos_text) 835d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang .setOnMenuItemClickListener(new OnMenuItemClickListener() { 836d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang public boolean onMenuItemClick(MenuItem item) { 837d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang gotoGallery(); 838d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang return true; 839d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang } 840d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang }); 841b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project gallery.setIcon(android.R.drawable.ic_menu_gallery); 842b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mGalleryItems.add(gallery); 843b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 844b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project { 845d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang MenuItem gallery = menu.add(MenuHelper.VIDEO_MODE_ITEM, 846d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang MENU_GALLERY_VIDEOS, 0, R.string.camera_gallery_photos_text) 847d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang .setOnMenuItemClickListener(new OnMenuItemClickListener() { 848d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang public boolean onMenuItemClick(MenuItem item) { 849d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang gotoGallery(); 850d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang return true; 851d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang } 852d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang }); 853b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project gallery.setIcon(android.R.drawable.ic_menu_gallery); 854b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mGalleryItems.add(gallery); 855b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 856b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 857d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang MenuItem item = menu.add(MenuHelper.GENERIC_ITEM, MENU_SETTINGS, 0, 858d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang R.string.settings) 859d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang .setOnMenuItemClickListener(new OnMenuItemClickListener() { 860d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang public boolean onMenuItemClick(MenuItem item) { 861d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang Intent intent = new Intent(); 862d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang intent.setClass(VideoCamera.this, CameraSettings.class); 863d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang startActivity(intent); 864d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang return true; 865d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang } 866d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang }); 867b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project item.setIcon(android.R.drawable.ic_menu_preferences); 868b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 869b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 870b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // from MediaRecorder.OnErrorListener 871b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void onError(MediaRecorder mr, int what, int extra) { 872b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (what == MediaRecorder.MEDIA_RECORDER_ERROR_UNKNOWN) { 873b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // We may have run out of space on the sdcard. 874b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project stopVideoRecording(); 8759a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project updateAndShowStorageHint(true); 876b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 877b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 878b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 8798d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project // from MediaRecorder.OnInfoListener 8808d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project public void onInfo(MediaRecorder mr, int what, int extra) { 8818d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) { 882de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mShutterButton.performClick(); 883d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang } else if (what 884d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang == MediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED) { 885de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mShutterButton.performClick(); 886de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project updateAndShowStorageHint(true); 8878d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project } 8888d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project } 8898d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project 8909c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project /* 8919c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project * Make sure we're not recording music playing in the background, ask 8929c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project * the MediaPlaybackService to pause playback. 8939c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project */ 8949c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project private void pauseAudioPlayback() { 8959c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project // Shamelessly copied from MediaPlaybackService.java, which 8969c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project // should be public, but isn't. 8979c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project Intent i = new Intent("com.android.music.musicservicecommand"); 8989c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project i.putExtra("command", "pause"); 8999c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project 9009c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project sendBroadcast(i); 9019c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project } 9029c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project 903b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void startVideoRecording() { 904b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "startVideoRecording"); 905b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (!mMediaRecorderRecording) { 906b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 9079a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project if (mStorageStatus != STORAGE_STATUS_OK) { 908b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Storage issue, ignore the start request"); 909b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return; 910b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 911b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 912b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // Check mMediaRecorder to see whether it is initialized or not. 913d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang if (mMediaRecorder == null && initializeVideo() == false) { 914b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.e(TAG, "Initialize video (MediaRecorder) failed."); 915b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return; 916b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 917b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 9189c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project pauseAudioPlayback(); 9199c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project 920b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project try { 921b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setOnErrorListener(this); 9228d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project mMediaRecorder.setOnInfoListener(this); 923b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.start(); // Recording is now started 924b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } catch (RuntimeException e) { 925b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.e(TAG, "Could not start media recorder. ", e); 926b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return; 927b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 928b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorderRecording = true; 929b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mRecordingStartTime = SystemClock.uptimeMillis(); 930b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project updateRecordingIndicator(true); 931b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mRecordingTimeView.setText(""); 932b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mRecordingTimeView.setVisibility(View.VISIBLE); 933b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mHandler.sendEmptyMessage(UPDATE_RECORD_TIME); 934b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenTimeoutInfinite(); 935de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project hideLastPictureButton(); 936b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 937b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 938b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 939b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void updateRecordingIndicator(boolean showRecording) { 940d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang int drawableId = showRecording 941d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang ? R.drawable.ic_camera_bar_indicator_record 942d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang : R.drawable.ic_camera_indicator_video; 943b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Drawable drawable = getResources().getDrawable(drawableId); 944b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mShutterButton.setImageDrawable(drawable); 945b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 946b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 9479bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private void stopVideoRecordingAndGetThumbnail() { 9489bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang stopVideoRecording(); 9499bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang acquireVideoThumb(); 950b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 951b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 952de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project private void stopVideoRecordingAndShowAlert() { 953de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project stopVideoRecording(); 9549bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang showAlert(); 955de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 956de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 9579bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private void showAlert() { 958b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int[] pickIds = {R.id.attach, R.id.cancel}; 959b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int[] normalIds = {R.id.gallery, R.id.share, R.id.discard}; 960b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int[] alwaysOnIds = {R.id.play}; 961b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int[] hideIds = pickIds; 962b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int[] connectIds = normalIds; 9639bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (mIsVideoCaptureIntent) { 964b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project hideIds = normalIds; 965b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project connectIds = pickIds; 966b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 967d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang for (int id : hideIds) { 968b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mPostPictureAlert.findViewById(id).setVisibility(View.GONE); 969b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 9708d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project ActionMenuButton shareButton = 9718d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project (ActionMenuButton) mPostPictureAlert.findViewById(R.id.share); 9728d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project shareButton.setRestricted( 9738d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project mCurrentVideoFileLength > SHARE_FILE_LENGTH_LIMIT); 974b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project connectAndFadeIn(connectIds); 975b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project connectAndFadeIn(alwaysOnIds); 976de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project hideLastPictureButton(); 977b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mPostPictureAlert.setVisibility(View.VISIBLE); 9789bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 9799bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // There are two cases we are here: 9809bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // (1) We are in a capture video intent, and we are reviewing the video 981095afa19556bf550262e3cccb9edacc04e6f726aOwen Lin // we just taken. 9829bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // (2) The thumbnail button is clicked: we review the video associated 9839bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // with the thumbnail. 9849bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // For the second case, we copy the associated URI and filename to 9859bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // mCurrentVideoUri and mCurrentVideoFilename, so the video frame shown 9869bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // and the target for actions (play, delete, ...) will be correct. 9879bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 9889bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (!mIsVideoCaptureIntent) { 9899bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mCurrentVideoUri = mThumbController.getUri(); 9909bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mCurrentVideoFilename = getDataPath(mCurrentVideoUri); 9919bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 9929bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 9939bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang String path = mCurrentVideoFilename; 9949bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (path != null) { 995101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin Bitmap videoFrame = Util.createVideoThumbnail(path); 9969bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mVideoFrame.setImageBitmap(videoFrame); 9979bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mVideoFrame.setVisibility(View.VISIBLE); 9989bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 999b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1000b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 10019bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private void hideAlert() { 1002de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mVideoFrame.setVisibility(View.INVISIBLE); 1003de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mPostPictureAlert.setVisibility(View.INVISIBLE); 1004de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project showLastPictureButton(); 1005de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 1006de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 1007b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void connectAndFadeIn(int[] connectIds) { 1008d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang for (int id : connectIds) { 1009b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project View view = mPostPictureAlert.findViewById(id); 1010b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project view.setOnClickListener(this); 1011b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Animation animation = new AlphaAnimation(0F, 1F); 1012b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project animation.setDuration(500); 10139bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang view.startAnimation(animation); 1014b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1015b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1016b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 10179bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private boolean isAlertVisible() { 1018b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return mPostPictureAlert.getVisibility() == View.VISIBLE; 1019b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1020b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1021b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void stopVideoRecording() { 1022b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "stopVideoRecording"); 1023b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project boolean needToRegisterRecording = false; 1024b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mMediaRecorderRecording || mMediaRecorder != null) { 1025b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mMediaRecorderRecording && mMediaRecorder != null) { 1026b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project try { 1027b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setOnErrorListener(null); 10288d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project mMediaRecorder.setOnInfoListener(null); 1029b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.stop(); 1030b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } catch (RuntimeException e) { 1031b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.e(TAG, "stop fail: " + e.getMessage()); 1032b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 10338d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project 1034b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoFilename = mCameraVideoFilename; 10358d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project try { 1036d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang mCurrentVideoFileLength = 1037d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang new File(mCurrentVideoFilename).length(); 10388d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project } catch (RuntimeException e) { 10398d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project Log.e(TAG, "get file length fail: " + e.getMessage()); 10408d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project mCurrentVideoFileLength = 0; 10418d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project } 1042d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang Log.v(TAG, "Setting current video filename: " 1043d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang + mCurrentVideoFilename); 1044b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project needToRegisterRecording = true; 1045b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorderRecording = false; 1046b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1047b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project releaseMediaRecorder(); 1048b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project updateRecordingIndicator(false); 1049b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mRecordingTimeView.setVisibility(View.GONE); 1050b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenTimeoutLong(); 1051b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 10529a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project if (needToRegisterRecording && mStorageStatus == STORAGE_STATUS_OK) { 10539a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project registerVideo(); 10549a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project } 1055b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1056b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCameraVideoFilename = null; 1057b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCameraVideoFileDescriptor = null; 1058b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1059b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1060b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void setScreenTimeoutSystemDefault() { 1061b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mHandler.removeMessages(CLEAR_SCREEN_DELAY); 1062b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project clearScreenOnFlag(); 1063b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1064b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1065b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void setScreenTimeoutLong() { 1066b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mHandler.removeMessages(CLEAR_SCREEN_DELAY); 1067b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenOnFlag(); 1068b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mHandler.sendEmptyMessageDelayed(CLEAR_SCREEN_DELAY, SCREEN_DELAY); 1069b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1070b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1071b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void setScreenTimeoutInfinite() { 1072b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mHandler.removeMessages(CLEAR_SCREEN_DELAY); 1073b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenOnFlag(); 1074b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1075b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1076b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void clearScreenOnFlag() { 1077b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Window w = getWindow(); 1078d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang final int flag = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; 1079d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang if ((w.getAttributes().flags & flag) != 0) { 1080d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang w.clearFlags(flag); 1081b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1082b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1083b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1084b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void setScreenOnFlag() { 1085b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Window w = getWindow(); 1086d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang final int flag = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; 1087d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang if ((w.getAttributes().flags & flag) == 0) { 1088d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang w.addFlags(flag); 1089b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1090b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1091b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 10929bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private void hideAlertAndStartPreview() { 10939bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang hideAlert(); 10949bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang initializeVideo(); 1095b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1096b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 10979bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private void hideAlertAndStartVideoRecording() { 10989bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang hideAlert(); 10999bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang startVideoRecording(); 1100b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1101b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 11029bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private void acquireVideoThumb() { 1103101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin Bitmap videoFrame = Util.createVideoThumbnail(mCurrentVideoFilename); 11049bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mThumbController.setData(mCurrentVideoUri, videoFrame); 1105de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 1106de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 11079bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private void showLastPictureButton() { 11089bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (!mIsVideoCaptureIntent) { 11099bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mLastPictureButton.setVisibility(View.VISIBLE); 1110de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 11119bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 1112de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 11139bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private void hideLastPictureButton() { 11149bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (!mIsVideoCaptureIntent) { 11159bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mLastPictureButton.setVisibility(View.INVISIBLE); 11169bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 1117de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 1118de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 11199bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private static ImageManager.DataLocation dataLocation() { 11209bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang return ImageManager.DataLocation.EXTERNAL; 1121de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 1122de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 11239bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private void updateLastVideo() { 1124101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin IImageList list = ImageManager.instance().allImages( 11259bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang this, 11269bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mContentResolver, 11279bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang dataLocation(), 11289bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang ImageManager.INCLUDE_VIDEOS, 11299bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang ImageManager.SORT_ASCENDING, 11309bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang ImageManager.CAMERA_IMAGE_BUCKET_ID); 11319bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang int count = list.getCount(); 11329bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (count > 0) { 1133d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang IImage image = list.getImageAt(count - 1); 11349bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang Uri uri = image.fullSizeImageUri(); 11359bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mThumbController.setData(uri, image.miniThumbBitmap()); 11369bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } else { 11379bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mThumbController.setData(null, null); 11389bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 11399bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang list.deactivate(); 1140b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1141b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 11429bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private static final String[] DATA_PATH_PROJECTION = new String[] { 11439bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang "_data" 11449bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang }; 11459bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 11469bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private String getDataPath(Uri uri) { 11479bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang Cursor c = null; 11489bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang try { 1149d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang c = mContentResolver.query(uri, DATA_PATH_PROJECTION, null, null, 1150d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang null); 11519bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (c != null && c.moveToFirst()) { 11529bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang return c.getString(0); 11539bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } else { 11549bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang return null; 11559bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 11569bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } finally { 115723c51b794e95c201290e36737f379c4bb8eefeaeRay Chen if (c != null) { 115823c51b794e95c201290e36737f379c4bb8eefeaeRay Chen c.close(); 115923c51b794e95c201290e36737f379c4bb8eefeaeRay Chen } 1160b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1161b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1162d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang 1163d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang private void updateRecordingTime() { 116423c51b794e95c201290e36737f379c4bb8eefeaeRay Chen if (!mMediaRecorderRecording) { 116523c51b794e95c201290e36737f379c4bb8eefeaeRay Chen return; 116623c51b794e95c201290e36737f379c4bb8eefeaeRay Chen } 1167d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang long now = SystemClock.uptimeMillis(); 1168d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang long delta = now - mRecordingStartTime; 1169d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang 1170d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // Starting a minute before reaching the max duration 1171d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // limit, we'll countdown the remaining time instead. 1172d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang boolean countdownRemainingTime = 1173d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang (delta >= MAX_RECORDING_DURATION_MS - 60000); 1174d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang 1175d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang if (countdownRemainingTime) { 1176d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang delta = Math.max(0, MAX_RECORDING_DURATION_MS - delta); 1177d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang } 1178d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang 1179d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang long seconds = (delta + 500) / 1000; // round to nearest 1180d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang long minutes = seconds / 60; 1181d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang long hours = minutes / 60; 1182d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang long remainderMinutes = minutes - (hours * 60); 1183d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang long remainderSeconds = seconds - (minutes * 60); 1184d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang 1185d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang String secondsString = Long.toString(remainderSeconds); 1186d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang if (secondsString.length() < 2) { 1187d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang secondsString = "0" + secondsString; 1188d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang } 1189d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang String minutesString = Long.toString(remainderMinutes); 1190d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang if (minutesString.length() < 2) { 1191d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang minutesString = "0" + minutesString; 1192d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang } 1193d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang String text = minutesString + ":" + secondsString; 1194d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang if (hours > 0) { 1195d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang String hoursString = Long.toString(hours); 1196d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang if (hoursString.length() < 2) { 1197d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang hoursString = "0" + hoursString; 1198d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang } 1199d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang text = hoursString + ":" + text; 1200d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang } 1201d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang mRecordingTimeView.setText(text); 1202d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang 1203d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang if (mRecordingTimeCountsDown != countdownRemainingTime) { 1204d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // Avoid setting the color on every update, do it only 1205d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // when it needs changing. 1206d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang 1207d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang mRecordingTimeCountsDown = countdownRemainingTime; 1208d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang 1209d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang int color = getResources().getColor( 1210d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang countdownRemainingTime 1211d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang ? R.color.recording_time_remaining_text 1212d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang : R.color.recording_time_elapsed_text); 1213d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang 1214d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang mRecordingTimeView.setTextColor(color); 1215d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang } 1216d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang 1217d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // Work around a limitation of the T-Mobile G1: The T-Mobile 1218d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // hardware blitter can't pixel-accurately scale and clip at the 1219d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // same time, and the SurfaceFlinger doesn't attempt to work around 1220d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // this limitation. In order to avoid visual corruption we must 1221d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // manually refresh the entire surface view when changing any 1222d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // overlapping view's contents. 1223d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang mVideoPreview.invalidate(); 1224d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang mHandler.sendEmptyMessageDelayed(UPDATE_RECORD_TIME, 1000); 1225d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang } 1226b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project} 1227