VideoCamera.java revision d8209aa01ae56ea27f551f621b419251bf80b265
1b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project/* 2b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 3b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * 4b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * you may not use this file except in compliance with the License. 6b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * You may obtain a copy of the License at 7b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * 8b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * 10b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * See the License for the specific language governing permissions and 14b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * limitations under the License. 15b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project */ 16b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 17b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectpackage com.android.camera; 18b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 19101d528d59f447847d5c6b7578642132c2b76f4fOwen Linimport com.android.camera.gallery.IImage; 20101d528d59f447847d5c6b7578642132c2b76f4fOwen Linimport com.android.camera.gallery.IImageList; 21101d528d59f447847d5c6b7578642132c2b76f4fOwen Linimport com.android.camera.gallery.Util; 22101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin 23b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.app.Activity; 24b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.BroadcastReceiver; 25b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.ContentResolver; 26b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.ContentValues; 27b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.Context; 28b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.Intent; 29b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.IntentFilter; 30b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.content.SharedPreferences; 31095afa19556bf550262e3cccb9edacc04e6f726aOwen Linimport android.database.Cursor; 32b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.graphics.Bitmap; 33b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.graphics.drawable.Drawable; 34b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.location.LocationManager; 35b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.media.MediaRecorder; 36b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.net.Uri; 37b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.Bundle; 38b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.Environment; 39b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.Handler; 40b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.Message; 41b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.StatFs; 42b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.os.SystemClock; 43b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.preference.PreferenceManager; 44b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.provider.MediaStore; 45b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.provider.MediaStore.Video; 46b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.text.format.DateFormat; 47b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.util.Log; 48b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.KeyEvent; 49b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.Menu; 50b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.MenuItem; 51d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Changimport android.view.MenuItem.OnMenuItemClickListener; 52b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.SurfaceHolder; 53b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.View; 54b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.Window; 55b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.WindowManager; 56b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.animation.AlphaAnimation; 57b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.view.animation.Animation; 58b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.widget.ImageView; 59b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.widget.TextView; 60b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectimport android.widget.Toast; 61b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 62d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Changimport java.io.File; 63d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Changimport java.io.FileDescriptor; 64d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Changimport java.io.IOException; 65d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Changimport java.text.SimpleDateFormat; 66d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Changimport java.util.ArrayList; 67d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Changimport java.util.Date; 68d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang 69b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectpublic class VideoCamera extends Activity implements View.OnClickListener, 70d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang ShutterButton.OnShutterButtonListener, SurfaceHolder.Callback, 71d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang MediaRecorder.OnErrorListener, MediaRecorder.OnInfoListener { 72b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 73b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final String TAG = "videocamera"; 74b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 75b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final int CLEAR_SCREEN_DELAY = 4; 76b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final int UPDATE_RECORD_TIME = 5; 77b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 78b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final int SCREEN_DELAY = 2 * 60 * 1000; 79b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 80b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final long NO_STORAGE_ERROR = -1L; 81b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final long CANNOT_STAT_ERROR = -2L; 82b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final long LOW_STORAGE_THRESHOLD = 512L * 1024L; 83e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project private static final long SHARE_FILE_LENGTH_LIMIT = 3L * 1024L * 1024L; 84b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 859a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project private static final int STORAGE_STATUS_OK = 0; 869a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project private static final int STORAGE_STATUS_LOW = 1; 879a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project private static final int STORAGE_STATUS_NONE = 2; 889a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project 89b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public static final int MENU_SETTINGS = 6; 90b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public static final int MENU_GALLERY_PHOTOS = 7; 91b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public static final int MENU_GALLERY_VIDEOS = 8; 92b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public static final int MENU_SAVE_GALLERY_PHOTO = 34; 93b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public static final int MENU_SAVE_PLAY_VIDEO = 35; 94b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public static final int MENU_SAVE_SELECT_VIDEO = 36; 95b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public static final int MENU_SAVE_NEW_VIDEO = 37; 96b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 97b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project SharedPreferences mPreferences; 98b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 99b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final float VIDEO_ASPECT_RATIO = 176.0f / 144.0f; 100b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project VideoPreview mVideoPreview; 101b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project SurfaceHolder mSurfaceHolder = null; 102b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project ImageView mVideoFrame; 1039bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 1049bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private boolean mIsVideoCaptureIntent; 1059bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // mLastPictureButton and mThumbController 1069bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // are non-null only if isVideoCaptureIntent() is true; 107de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project private ImageView mLastPictureButton; 1089bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private ThumbnailController mThumbController; 109b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1108d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project private static final int MAX_RECORDING_DURATION_MS = 10 * 60 * 1000; 1118d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project 1129a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project private int mStorageStatus = STORAGE_STATUS_OK; 1139a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project 114b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private MediaRecorder mMediaRecorder; 115b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private boolean mMediaRecorderRecording = false; 116b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private long mRecordingStartTime; 117b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // The video file that the hardware camera is about to record into 118b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // (or is recording into.) 119b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private String mCameraVideoFilename; 120b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private FileDescriptor mCameraVideoFileDescriptor; 121b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 122b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // The video file that has already been recorded, and that is being 123b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // examined by the user. 124b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private String mCurrentVideoFilename; 1258d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project private long mCurrentVideoFileLength = 0L; 126b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private Uri mCurrentVideoUri; 127b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private ContentValues mCurrentVideoValues; 128b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 129b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project boolean mPausing = false; 130b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 131d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang private ContentResolver mContentResolver; 132b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 133b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int mCurrentZoomIndex = 0; 134b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 135b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private ShutterButton mShutterButton; 136b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private TextView mRecordingTimeView; 1378d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project private boolean mRecordingTimeCountsDown = false; 138b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 139b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project ArrayList<MenuItem> mGalleryItems = new ArrayList<MenuItem>(); 140b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 141b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project View mPostPictureAlert; 142b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project LocationManager mLocationManager = null; 143b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 144b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private Handler mHandler = new MainHandler(); 145b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 146d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // This Handler is used to post message back onto the main thread of the 147d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // application 148b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private class MainHandler extends Handler { 149b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 150b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void handleMessage(Message msg) { 151b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project switch (msg.what) { 152b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 153b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case CLEAR_SCREEN_DELAY: { 154b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project clearScreenOnFlag(); 155b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 156b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 157b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 158b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case UPDATE_RECORD_TIME: { 159d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang updateRecordingTime(); 160b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 161b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 162b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 163b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project default: 164b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Unhandled message: " + msg.what); 165b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 166b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 167b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 168b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project }; 169b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 170b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 171b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 172b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void onReceive(Context context, Intent intent) { 173b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String action = intent.getAction(); 174b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (action.equals(Intent.ACTION_MEDIA_EJECT)) { 1759a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project updateAndShowStorageHint(false); 176b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project stopVideoRecording(); 177b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project initializeVideo(); 178b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else if (action.equals(Intent.ACTION_MEDIA_MOUNTED)) { 1799a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project updateAndShowStorageHint(true); 180b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project initializeVideo(); 181b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else if (action.equals(Intent.ACTION_MEDIA_UNMOUNTED)) { 182b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // SD card unavailable 1839a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project // handled in ACTION_MEDIA_EJECT 184b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else if (action.equals(Intent.ACTION_MEDIA_SCANNER_STARTED)) { 185d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang Toast.makeText(VideoCamera.this, 186d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang getResources().getString(R.string.wait), 5000); 187b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else if (action.equals(Intent.ACTION_MEDIA_SCANNER_FINISHED)) { 1889a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project updateAndShowStorageHint(true); 189b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 190b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 191b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project }; 192b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 193d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang private static String createName(long dateTaken) { 194b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return DateFormat.format("yyyy-MM-dd kk.mm.ss", dateTaken).toString(); 195b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 196b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 197b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project /** Called with the activity is first created. */ 198b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 199b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void onCreate(Bundle icicle) { 200b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project super.onCreate(icicle); 201b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 202d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang mLocationManager = (LocationManager) getSystemService( 203d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang Context.LOCATION_SERVICE); 204b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 205b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mPreferences = PreferenceManager.getDefaultSharedPreferences(this); 206b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mContentResolver = getContentResolver(); 207b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 208b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project //setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT); 209b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project requestWindowFeature(Window.FEATURE_PROGRESS); 210b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setContentView(R.layout.video_camera); 211b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 212b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mVideoPreview = (VideoPreview) findViewById(R.id.camera_preview); 213b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mVideoPreview.setAspectRatio(VIDEO_ASPECT_RATIO); 214b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 215b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // don't set mSurfaceHolder here. We have it set ONLY within 216b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // surfaceCreated / surfaceDestroyed, other parts of the code 217b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // assume that when it is set, the surface is also set. 218b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project SurfaceHolder holder = mVideoPreview.getHolder(); 219b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project holder.addCallback(this); 220b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 221b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 222b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mPostPictureAlert = findViewById(R.id.post_picture_panel); 223b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 224b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int[] ids = new int[]{R.id.play, R.id.share, R.id.discard, 225b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project R.id.cancel, R.id.attach}; 226b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project for (int id : ids) { 227b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project findViewById(id).setOnClickListener(this); 228b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 229b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 230b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mShutterButton = (ShutterButton) findViewById(R.id.shutter_button); 231b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mShutterButton.setOnShutterButtonListener(this); 232b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mRecordingTimeView = (TextView) findViewById(R.id.recording_time); 233b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mVideoFrame = (ImageView) findViewById(R.id.video_frame); 2349bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mIsVideoCaptureIntent = isVideoCaptureIntent(); 2359bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (!mIsVideoCaptureIntent) { 236d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang mLastPictureButton = (ImageView) findViewById( 237d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang R.id.last_picture_button); 2389bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mLastPictureButton.setOnClickListener(this); 239d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang Drawable frame = getResources().getDrawable( 240d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang R.drawable.frame_thumbnail); 2419bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mThumbController = new ThumbnailController(mLastPictureButton, 2429bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang frame, mContentResolver); 2439bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mThumbController.loadData(ImageManager.getLastVideoThumbPath()); 2449bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 245b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 246b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 247e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project private void startShareVideoActivity() { 2488d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project if (mCurrentVideoFileLength > SHARE_FILE_LENGTH_LIMIT) { 249e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project Toast.makeText(VideoCamera.this, 250e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project R.string.too_large_to_attach, Toast.LENGTH_LONG).show(); 251e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project return; 252e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project } 253e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project Intent intent = new Intent(); 254e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project intent.setAction(Intent.ACTION_SEND); 255e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project intent.setType("video/3gpp"); 256e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project intent.putExtra(Intent.EXTRA_STREAM, mCurrentVideoUri); 257e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project try { 258d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang startActivity(Intent.createChooser( 259d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang intent, getText(R.string.sendVideo))); 260e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project } catch (android.content.ActivityNotFoundException ex) { 261d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang Toast.makeText(VideoCamera.this, R.string.no_way_to_share_video, 262d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang Toast.LENGTH_SHORT).show(); 263e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project } 264e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project } 265e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project 266b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void onClick(View v) { 267b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project switch (v.getId()) { 268b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 269b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case R.id.gallery: 270b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project MenuHelper.gotoCameraVideoGallery(this); 271b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 272b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 273b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case R.id.attach: 274b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project doReturnToCaller(true); 275b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 276b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 277b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case R.id.cancel: 278b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project doReturnToCaller(false); 279b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 280b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 281b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case R.id.discard: { 2827638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen Runnable deleteCallback = new Runnable() { 2837638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen public void run() { 2847638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen discardCurrentVideoAndStartPreview(); 2857638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen } 2867638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen }; 2877638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen MenuHelper.deleteVideo(this, deleteCallback); 288b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 289b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 290b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 291b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case R.id.share: { 292e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project startShareVideoActivity(); 293b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 294b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 295b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 296b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case R.id.play: { 297b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project doPlayCurrentVideo(); 298b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 299b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 300de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 301de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project case R.id.last_picture_button: { 3029bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang stopVideoRecordingAndShowAlert(); 303de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project break; 304de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 305b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 306b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 307b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 308b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void onShutterButtonFocus(ShutterButton button, boolean pressed) { 309de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project // Do nothing (everything happens in onShutterButtonClick). 310de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 311de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 312de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project public void onShutterButtonClick(ShutterButton button) { 313b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project switch (button.getId()) { 314b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case R.id.shutter_button: 315de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project if (mMediaRecorderRecording) { 3169bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (mIsVideoCaptureIntent) { 317de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project stopVideoRecordingAndShowAlert(); 318b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 3199bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang stopVideoRecordingAndGetThumbnail(); 3209bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang initializeVideo(); 3219bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 3229bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } else if (isAlertVisible()) { 3239bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (mIsVideoCaptureIntent) { 3249bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang discardCurrentVideoAndStartPreview(); 3259bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } else { 3269bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang hideAlertAndStartVideoRecording(); 327b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 328de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } else { 329de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project startVideoRecording(); 330b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 331b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 332b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 333b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 334b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 335b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void doPlayCurrentVideo() { 336b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.e(TAG, "Playing current video: " + mCurrentVideoUri); 337b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Intent intent = new Intent(Intent.ACTION_VIEW, mCurrentVideoUri); 338b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project try { 339b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project startActivity(intent); 340b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } catch (android.content.ActivityNotFoundException ex) { 341b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.e(TAG, "Couldn't view video " + mCurrentVideoUri, ex); 342b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 343b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 344b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 345b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void discardCurrentVideoAndStartPreview() { 346b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project deleteCurrentVideo(); 3479bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang hideAlertAndStartPreview(); 348b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 349b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 350b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private OnScreenHint mStorageHint; 351b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 3529a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project private void updateAndShowStorageHint(boolean mayHaveSd) { 3539a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project mStorageStatus = getStorageStatus(mayHaveSd); 3549a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project showStorageHint(); 3559a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project } 3569a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project 3579a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project private void showStorageHint() { 358b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String errorMessage = null; 3599a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project switch (mStorageStatus) { 3609a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project case STORAGE_STATUS_NONE: 361b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project errorMessage = getString(R.string.no_storage); 3629a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project break; 3639a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project case STORAGE_STATUS_LOW: 364b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project errorMessage = getString(R.string.spaceIsLow_content); 365b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 366b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (errorMessage != null) { 367b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mStorageHint == null) { 368b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mStorageHint = OnScreenHint.makeText(this, errorMessage); 369b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 370b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mStorageHint.setText(errorMessage); 371b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 372b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mStorageHint.show(); 373b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else if (mStorageHint != null) { 374b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mStorageHint.cancel(); 375b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mStorageHint = null; 376b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 377b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 378b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 3799a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project private int getStorageStatus(boolean mayHaveSd) { 3809a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project long remaining = mayHaveSd ? getAvailableStorage() : NO_STORAGE_ERROR; 3819a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project if (remaining == NO_STORAGE_ERROR) { 3829a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project return STORAGE_STATUS_NONE; 3839a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project } 3849a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project return remaining < LOW_STORAGE_THRESHOLD 3859a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project ? STORAGE_STATUS_LOW : STORAGE_STATUS_OK; 3869a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project } 3879a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project 388b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 389b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void onResume() { 390b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project super.onResume(); 391b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 392b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenTimeoutLong(); 393b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 394b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mPausing = false; 395b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 396b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // install an intent filter to receive SD card related events. 397d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang IntentFilter intentFilter = 398d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang new IntentFilter(Intent.ACTION_MEDIA_MOUNTED); 399b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project intentFilter.addAction(Intent.ACTION_MEDIA_EJECT); 400b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project intentFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED); 401b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_STARTED); 402b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED); 403b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project intentFilter.addDataScheme("file"); 404b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project registerReceiver(mReceiver, intentFilter); 4059a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project mStorageStatus = getStorageStatus(true); 4069a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project 4079a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project mHandler.postDelayed(new Runnable() { 4089a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project public void run() { 4099a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project showStorageHint(); 4109a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project } 4119a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project }, 200); 412b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 4139bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang initializeVideo(); 414b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 415b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 416b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 417b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void onStop() { 418b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenTimeoutSystemDefault(); 419b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project super.onStop(); 420b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 421b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 422b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 423b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project protected void onPause() { 424b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project super.onPause(); 425b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 4269bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // This is similar to what mShutterButton.performClick() does, 4279bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // but not quite the same. 4289bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (mMediaRecorderRecording) { 4299bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (mIsVideoCaptureIntent) { 4309bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang stopVideoRecordingAndShowAlert(); 4319bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } else { 4329bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang stopVideoRecordingAndGetThumbnail(); 4339bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 4349bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } else { 4359bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang stopVideoRecording(); 4369bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 437b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 438b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mPausing = true; 439b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 4409c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project unregisterReceiver(mReceiver); 441b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenTimeoutSystemDefault(); 442b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 4439bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (!mIsVideoCaptureIntent) { 4449bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mThumbController.storeData(ImageManager.getLastVideoThumbPath()); 4459bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 446095afa19556bf550262e3cccb9edacc04e6f726aOwen Lin 447b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mStorageHint != null) { 448b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mStorageHint.cancel(); 449b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mStorageHint = null; 450b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 451b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 452b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 453b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 454b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public boolean onKeyDown(int keyCode, KeyEvent event) { 455b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenTimeoutLong(); 456b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 457b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project switch (keyCode) { 458b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case KeyEvent.KEYCODE_BACK: 459b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mMediaRecorderRecording) { 460de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mShutterButton.performClick(); 461b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 462d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang } else if (isAlertVisible()) { 4639bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang hideAlertAndStartPreview(); 464b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 465b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 466b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 467b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case KeyEvent.KEYCODE_CAMERA: 468b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (event.getRepeatCount() == 0) { 469de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mShutterButton.performClick(); 470b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 471b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 472de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project break; 473b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case KeyEvent.KEYCODE_DPAD_CENTER: 474b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (event.getRepeatCount() == 0) { 475de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mShutterButton.performClick(); 476de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project return true; 477b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 478b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 479b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case KeyEvent.KEYCODE_MENU: 480b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mMediaRecorderRecording) { 481de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mShutterButton.performClick(); 482b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 483b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 484b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 485b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 486b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 487b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return super.onKeyDown(keyCode, event); 488b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 489b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 490b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 491b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public boolean onKeyUp(int keyCode, KeyEvent event) { 492b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project switch(keyCode) { 493b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case KeyEvent.KEYCODE_CAMERA: 494b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mShutterButton.setPressed(false); 495b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 496b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 497b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return super.onKeyUp(keyCode, event); 498b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 499b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 500b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 501314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber if (mPausing) { 502314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber // We're pausing, the screen is off and we already stopped 503314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber // video recording. We don't want to start the camera again 504314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber // in this case in order to conserve power. 505314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber // The fact that surfaceChanged is called _after_ an onPause appears 506314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber // to be legitimate since in that case the lockscreen always returns 507314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber // to portrait orientation possibly triggering the notification. 508314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber return; 509314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber } 510314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber 511b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project stopVideoRecording(); 512b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project initializeVideo(); 513b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 514b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 515b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void surfaceCreated(SurfaceHolder holder) { 516b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mSurfaceHolder = holder; 517b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 518b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 519b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void surfaceDestroyed(SurfaceHolder holder) { 520b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mSurfaceHolder = null; 521b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 522b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 523b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project void gotoGallery() { 524b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project MenuHelper.gotoCameraVideoGallery(this); 525b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 526b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 527b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 528b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public boolean onPrepareOptionsMenu(Menu menu) { 529b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project super.onPrepareOptionsMenu(menu); 530b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 531b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project for (int i = 1; i <= MenuHelper.MENU_ITEM_MAX; i++) { 532b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (i != MenuHelper.GENERIC_ITEM) { 533b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project menu.setGroupVisible(i, false); 534b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 535b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 536b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 537b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project menu.setGroupVisible(MenuHelper.VIDEO_MODE_ITEM, true); 538b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 539b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 540b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 541b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 542b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public boolean onCreateOptionsMenu(Menu menu) { 543b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project super.onCreateOptionsMenu(menu); 544b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 5459bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (mIsVideoCaptureIntent) { 546b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // No options menu for attach mode. 547b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return false; 548b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 549b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project addBaseMenuItems(menu); 550d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang int menuFlags = MenuHelper.INCLUDE_ALL 551d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang & ~MenuHelper.INCLUDE_ROTATE_MENU 552095afa19556bf550262e3cccb9edacc04e6f726aOwen Lin & ~MenuHelper.INCLUDE_DETAILS_MENU; 553b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project MenuHelper.addImageMenuItems( 554b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project menu, 555095afa19556bf550262e3cccb9edacc04e6f726aOwen Lin menuFlags, 556b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project false, 557b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project VideoCamera.this, 558b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mHandler, 559b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 560b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // Handler for deletion 561b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project new Runnable() { 562b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void run() { 563b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // What do we do here? 564b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // mContentResolver.delete(uri, null, null); 565b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 566b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project }, 567b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project new MenuHelper.MenuInvoker() { 568b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void run(final MenuHelper.MenuCallback cb) { 569b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 570b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project }); 571b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 572d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang MenuItem gallery = menu.add(MenuHelper.IMAGE_SAVING_ITEM, 573d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang MENU_SAVE_GALLERY_PHOTO, 0, 574d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang R.string.camera_gallery_photos_text) 575d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang .setOnMenuItemClickListener( 576d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang new MenuItem.OnMenuItemClickListener() { 577d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang public boolean onMenuItemClick(MenuItem item) { 578d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang gotoGallery(); 579d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang return true; 580d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang } 581d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang }); 582b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project gallery.setIcon(android.R.drawable.ic_menu_gallery); 583b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 584b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 585b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 586b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 587b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private boolean isVideoCaptureIntent() { 588b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String action = getIntent().getAction(); 589b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return (MediaStore.ACTION_VIDEO_CAPTURE.equals(action)); 590b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 591b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 592b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void doReturnToCaller(boolean success) { 593b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Intent resultIntent = new Intent(); 594b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int resultCode; 595b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (success) { 596b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project resultCode = RESULT_OK; 597b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project resultIntent.setData(mCurrentVideoUri); 598b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 599b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project resultCode = RESULT_CANCELED; 600b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 601b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setResult(resultCode, resultIntent); 602b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project finish(); 603b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 604b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 605b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project /** 606b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * Returns 607b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * @return number of bytes available, or an ERROR code. 608b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project */ 609b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static long getAvailableStorage() { 610b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project try { 611b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (!ImageManager.hasStorage()) { 612b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return NO_STORAGE_ERROR; 613b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 614d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang String storageDirectory = Environment 615d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang .getExternalStorageDirectory().toString(); 616b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project StatFs stat = new StatFs(storageDirectory); 617d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang return ((long) stat.getAvailableBlocks() 618d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang * (long) stat.getBlockSize()); 619b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 620b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } catch (Exception ex) { 621b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // if we can't stat the filesystem then we don't know how many 622b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // free bytes exist. It might be zero but just leave it 623b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // blank since we really don't know. 624b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return CANNOT_STAT_ERROR; 625b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 626b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 627b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 628b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void cleanupEmptyFile() { 629b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mCameraVideoFilename != null) { 630b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project File f = new File(mCameraVideoFilename); 631b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (f.length() == 0 && f.delete()) { 632b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Empty video file deleted: " + mCameraVideoFilename); 633b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCameraVideoFilename = null; 634b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 635b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 636b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 637b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 6389bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // initializeVideo() starts preview and prepare media recorder. 639b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // Returns false if initializeVideo fails 640b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private boolean initializeVideo() { 641b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "initializeVideo"); 6429bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 6439bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // We will call initializeVideo() again when the alert is hidden. 6449bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (isAlertVisible()) return false; 6459bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 646b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Intent intent = getIntent(); 647b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Bundle myExtras = intent.getExtras(); 648b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 6499bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (mIsVideoCaptureIntent && myExtras != null) { 650b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Uri saveUri = (Uri) myExtras.getParcelable(MediaStore.EXTRA_OUTPUT); 651b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (saveUri != null) { 652b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project try { 653b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCameraVideoFileDescriptor = mContentResolver. 654b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project openFileDescriptor(saveUri, "rw").getFileDescriptor(); 655b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoUri = saveUri; 656d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang } catch (java.io.FileNotFoundException ex) { 657b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // invalid uri 658b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.e(TAG, ex.toString()); 659b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 660b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 661b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 662b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project releaseMediaRecorder(); 663b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 664b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mSurfaceHolder == null) { 665b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "SurfaceHolder is null"); 666b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return false; 667b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 668b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 669b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder = new MediaRecorder(); 670b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 671d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); 672b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); 673b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); 674b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 6758d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project mMediaRecorder.setMaxDuration(MAX_RECORDING_DURATION_MS); 6768d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project 6779a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project if (mStorageStatus != STORAGE_STATUS_OK) { 678b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setOutputFile("/dev/null"); 679b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 680d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // We try Uri in intent first. If it doesn't work, use our own 681d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // instead. 682b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mCameraVideoFileDescriptor != null) { 683b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setOutputFile(mCameraVideoFileDescriptor); 684b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 685b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project createVideoPath(); 686b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setOutputFile(mCameraVideoFilename); 687b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 688b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 689b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 690d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang boolean videoQualityHigh = getBooleanPreference( 691d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang CameraSettings.KEY_VIDEO_QUALITY, 692b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project CameraSettings.DEFAULT_VIDEO_QUALITY_VALUE); 693b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 694b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (intent.hasExtra(MediaStore.EXTRA_VIDEO_QUALITY)) { 695d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang int extraVideoQuality = intent.getIntExtra( 696d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang MediaStore.EXTRA_VIDEO_QUALITY, 0); 697b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project videoQualityHigh = (extraVideoQuality > 0); 698b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 699b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 700b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // Use the same frame rate for both, since internally 701b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // if the frame rate is too large, it can cause camera to become 702b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // unstable. We need to fix the MediaRecorder to disable the support 703b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // of setting frame rate for now. 704b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setVideoFrameRate(20); 705b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (videoQualityHigh) { 706d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang mMediaRecorder.setVideoSize(352, 288); 707b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 708d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang mMediaRecorder.setVideoSize(176, 144); 709b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 710b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263); 711d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); 712b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface()); 713de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 714de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project long remaining = getAvailableStorage(); 715de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project // remaining >= LOW_STORAGE_THRESHOLD at this point, reserve a quarter 716d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // of that to make it more likely that recording can complete 717d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // successfully. 718de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project try { 719d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang mMediaRecorder.setMaxFileSize(remaining - 720d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang LOW_STORAGE_THRESHOLD / 4); 721de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } catch (RuntimeException exception) { 722de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project // We are going to ignore failure of setMaxFileSize here, as 723de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project // a) The composer selected may simply not support it, or 724de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project // b) The underlying media framework may not handle 64-bit range 725de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project // on the size restriction. 726de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 727de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 728b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project try { 729b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.prepare(); 730b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } catch (IOException exception) { 731b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.e(TAG, "prepare failed for " + mCameraVideoFilename); 732b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project releaseMediaRecorder(); 733b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // TODO: add more exception handling logic here 734b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return false; 735b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 736b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorderRecording = false; 7379bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 7389bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (!mIsVideoCaptureIntent && !mThumbController.isUriValid()) { 7399bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang updateLastVideo(); 7409bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 7419bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 7429bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (!mIsVideoCaptureIntent) { 7439bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mThumbController.updateDisplayIfNeeded(); 7449bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 7459bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 746b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 747b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 748b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 749b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void releaseMediaRecorder() { 750b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Releasing media recorder."); 751b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mMediaRecorder != null) { 752b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project cleanupEmptyFile(); 753b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.reset(); 754b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.release(); 755b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder = null; 756b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 757b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 758b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 759b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private int getIntPreference(String key, int defaultValue) { 760b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String s = mPreferences.getString(key, ""); 761b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int result = defaultValue; 762b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project try { 763b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project result = Integer.parseInt(s); 764b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } catch (NumberFormatException e) { 765b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // Ignore, result is already the default value. 766b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 767b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return result; 768b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 769b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 770b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private boolean getBooleanPreference(String key, boolean defaultValue) { 771b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return getIntPreference(key, defaultValue ? 1 : 0) != 0; 772b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 773b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 774b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void createVideoPath() { 775b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project long dateTaken = System.currentTimeMillis(); 776b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String title = createName(dateTaken); 777b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String displayName = title + ".3gp"; // Used when emailing. 778b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String cameraDirPath = ImageManager.CAMERA_IMAGE_BUCKET_NAME; 779b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project File cameraDir = new File(cameraDirPath); 780b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project cameraDir.mkdirs(); 781b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project SimpleDateFormat dateFormat = new SimpleDateFormat( 782b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project getString(R.string.video_file_name_format)); 783b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Date date = new Date(dateTaken); 784b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String filepart = dateFormat.format(date); 785b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String filename = cameraDirPath + "/" + filepart + ".3gp"; 786b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project ContentValues values = new ContentValues(7); 787b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project values.put(Video.Media.TITLE, title); 788b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project values.put(Video.Media.DISPLAY_NAME, displayName); 789b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project values.put(Video.Media.DESCRIPTION, ""); 790b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project values.put(Video.Media.DATE_TAKEN, dateTaken); 791b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project values.put(Video.Media.MIME_TYPE, "video/3gpp"); 792b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project values.put(Video.Media.DATA, filename); 793b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCameraVideoFilename = filename; 794b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Current camera video filename: " + mCameraVideoFilename); 795b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoValues = values; 796b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 797b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 798b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void registerVideo() { 799b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mCameraVideoFileDescriptor == null) { 800b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Uri videoTable = Uri.parse("content://media/external/video/media"); 801b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoUri = mContentResolver.insert(videoTable, 802b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoValues); 803b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Current video URI: " + mCurrentVideoUri); 804b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 805b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoValues = null; 806b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 807b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 808b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void deleteCurrentVideo() { 809b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mCurrentVideoFilename != null) { 810b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project deleteVideoFile(mCurrentVideoFilename); 811b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoFilename = null; 812b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 813b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mCurrentVideoUri != null) { 814b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mContentResolver.delete(mCurrentVideoUri, null, null); 815b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoUri = null; 816b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 817de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project updateAndShowStorageHint(true); 818b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 819b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 820b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void deleteVideoFile(String fileName) { 821b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Deleting video " + fileName); 822b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project File f = new File(fileName); 823d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang if (!f.delete()) { 824b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Could not delete " + fileName); 825b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 826b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 827b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 828b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void addBaseMenuItems(Menu menu) { 829b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project MenuHelper.addSwitchModeMenuItem(menu, this, false); 830b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project { 831d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang MenuItem gallery = menu.add(MenuHelper.IMAGE_MODE_ITEM, 832d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang MENU_GALLERY_PHOTOS, 0, R.string.camera_gallery_photos_text) 833d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang .setOnMenuItemClickListener(new OnMenuItemClickListener() { 834d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang public boolean onMenuItemClick(MenuItem item) { 835d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang gotoGallery(); 836d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang return true; 837d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang } 838d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang }); 839b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project gallery.setIcon(android.R.drawable.ic_menu_gallery); 840b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mGalleryItems.add(gallery); 841b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 842b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project { 843d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang MenuItem gallery = menu.add(MenuHelper.VIDEO_MODE_ITEM, 844d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang MENU_GALLERY_VIDEOS, 0, R.string.camera_gallery_photos_text) 845d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang .setOnMenuItemClickListener(new OnMenuItemClickListener() { 846d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang public boolean onMenuItemClick(MenuItem item) { 847d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang gotoGallery(); 848d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang return true; 849d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang } 850d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang }); 851b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project gallery.setIcon(android.R.drawable.ic_menu_gallery); 852b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mGalleryItems.add(gallery); 853b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 854b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 855d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang MenuItem item = menu.add(MenuHelper.GENERIC_ITEM, MENU_SETTINGS, 0, 856d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang R.string.settings) 857d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang .setOnMenuItemClickListener(new OnMenuItemClickListener() { 858d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang public boolean onMenuItemClick(MenuItem item) { 859d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang Intent intent = new Intent(); 860d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang intent.setClass(VideoCamera.this, CameraSettings.class); 861d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang startActivity(intent); 862d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang return true; 863d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang } 864d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang }); 865b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project item.setIcon(android.R.drawable.ic_menu_preferences); 866b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 867b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 868b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // from MediaRecorder.OnErrorListener 869b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void onError(MediaRecorder mr, int what, int extra) { 870b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (what == MediaRecorder.MEDIA_RECORDER_ERROR_UNKNOWN) { 871b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // We may have run out of space on the sdcard. 872b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project stopVideoRecording(); 8739a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project updateAndShowStorageHint(true); 874b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 875b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 876b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 8778d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project // from MediaRecorder.OnInfoListener 8788d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project public void onInfo(MediaRecorder mr, int what, int extra) { 8798d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) { 880de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mShutterButton.performClick(); 881d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang } else if (what 882d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang == MediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED) { 883de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mShutterButton.performClick(); 884de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project updateAndShowStorageHint(true); 8858d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project } 8868d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project } 8878d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project 8889c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project /* 8899c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project * Make sure we're not recording music playing in the background, ask 8909c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project * the MediaPlaybackService to pause playback. 8919c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project */ 8929c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project private void pauseAudioPlayback() { 8939c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project // Shamelessly copied from MediaPlaybackService.java, which 8949c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project // should be public, but isn't. 8959c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project Intent i = new Intent("com.android.music.musicservicecommand"); 8969c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project i.putExtra("command", "pause"); 8979c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project 8989c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project sendBroadcast(i); 8999c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project } 9009c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project 901b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void startVideoRecording() { 902b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "startVideoRecording"); 903b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (!mMediaRecorderRecording) { 904b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 9059a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project if (mStorageStatus != STORAGE_STATUS_OK) { 906b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Storage issue, ignore the start request"); 907b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return; 908b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 909b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 910b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // Check mMediaRecorder to see whether it is initialized or not. 911d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang if (mMediaRecorder == null && initializeVideo() == false) { 912b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.e(TAG, "Initialize video (MediaRecorder) failed."); 913b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return; 914b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 915b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 9169c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project pauseAudioPlayback(); 9179c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project 918b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project try { 919b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setOnErrorListener(this); 9208d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project mMediaRecorder.setOnInfoListener(this); 921b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.start(); // Recording is now started 922b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } catch (RuntimeException e) { 923b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.e(TAG, "Could not start media recorder. ", e); 924b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return; 925b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 926b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorderRecording = true; 927b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mRecordingStartTime = SystemClock.uptimeMillis(); 928b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project updateRecordingIndicator(true); 929b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mRecordingTimeView.setText(""); 930b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mRecordingTimeView.setVisibility(View.VISIBLE); 931b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mHandler.sendEmptyMessage(UPDATE_RECORD_TIME); 932b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenTimeoutInfinite(); 933de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project hideLastPictureButton(); 934b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 935b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 936b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 937b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void updateRecordingIndicator(boolean showRecording) { 938d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang int drawableId = showRecording 939d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang ? R.drawable.ic_camera_bar_indicator_record 940d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang : R.drawable.ic_camera_indicator_video; 941b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Drawable drawable = getResources().getDrawable(drawableId); 942b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mShutterButton.setImageDrawable(drawable); 943b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 944b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 9459bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private void stopVideoRecordingAndGetThumbnail() { 9469bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang stopVideoRecording(); 9479bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang acquireVideoThumb(); 948b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 949b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 950de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project private void stopVideoRecordingAndShowAlert() { 951de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project stopVideoRecording(); 9529bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang showAlert(); 953de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 954de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 9559bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private void showAlert() { 956b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int[] pickIds = {R.id.attach, R.id.cancel}; 957b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int[] normalIds = {R.id.gallery, R.id.share, R.id.discard}; 958b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int[] alwaysOnIds = {R.id.play}; 959b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int[] hideIds = pickIds; 960b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int[] connectIds = normalIds; 9619bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (mIsVideoCaptureIntent) { 962b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project hideIds = normalIds; 963b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project connectIds = pickIds; 964b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 965d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang for (int id : hideIds) { 966b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mPostPictureAlert.findViewById(id).setVisibility(View.GONE); 967b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 9688d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project ActionMenuButton shareButton = 9698d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project (ActionMenuButton) mPostPictureAlert.findViewById(R.id.share); 9708d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project shareButton.setRestricted( 9718d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project mCurrentVideoFileLength > SHARE_FILE_LENGTH_LIMIT); 972b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project connectAndFadeIn(connectIds); 973b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project connectAndFadeIn(alwaysOnIds); 974de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project hideLastPictureButton(); 975b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mPostPictureAlert.setVisibility(View.VISIBLE); 9769bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 9779bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // There are two cases we are here: 9789bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // (1) We are in a capture video intent, and we are reviewing the video 979095afa19556bf550262e3cccb9edacc04e6f726aOwen Lin // we just taken. 9809bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // (2) The thumbnail button is clicked: we review the video associated 9819bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // with the thumbnail. 9829bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // For the second case, we copy the associated URI and filename to 9839bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // mCurrentVideoUri and mCurrentVideoFilename, so the video frame shown 9849bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // and the target for actions (play, delete, ...) will be correct. 9859bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 9869bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (!mIsVideoCaptureIntent) { 9879bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mCurrentVideoUri = mThumbController.getUri(); 9889bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mCurrentVideoFilename = getDataPath(mCurrentVideoUri); 9899bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 9909bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 9919bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang String path = mCurrentVideoFilename; 9929bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (path != null) { 993101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin Bitmap videoFrame = Util.createVideoThumbnail(path); 9949bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mVideoFrame.setImageBitmap(videoFrame); 9959bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mVideoFrame.setVisibility(View.VISIBLE); 9969bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 997b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 998b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 9999bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private void hideAlert() { 1000de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mVideoFrame.setVisibility(View.INVISIBLE); 1001de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mPostPictureAlert.setVisibility(View.INVISIBLE); 1002de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project showLastPictureButton(); 1003de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 1004de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 1005b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void connectAndFadeIn(int[] connectIds) { 1006d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang for (int id : connectIds) { 1007b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project View view = mPostPictureAlert.findViewById(id); 1008b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project view.setOnClickListener(this); 1009b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Animation animation = new AlphaAnimation(0F, 1F); 1010b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project animation.setDuration(500); 10119bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang view.startAnimation(animation); 1012b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1013b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1014b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 10159bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private boolean isAlertVisible() { 1016b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return mPostPictureAlert.getVisibility() == View.VISIBLE; 1017b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1018b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1019b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void stopVideoRecording() { 1020b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "stopVideoRecording"); 1021b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project boolean needToRegisterRecording = false; 1022b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mMediaRecorderRecording || mMediaRecorder != null) { 1023b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mMediaRecorderRecording && mMediaRecorder != null) { 1024b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project try { 1025b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setOnErrorListener(null); 10268d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project mMediaRecorder.setOnInfoListener(null); 1027b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.stop(); 1028b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } catch (RuntimeException e) { 1029b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.e(TAG, "stop fail: " + e.getMessage()); 1030b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 10318d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project 1032b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoFilename = mCameraVideoFilename; 10338d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project try { 1034d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang mCurrentVideoFileLength = 1035d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang new File(mCurrentVideoFilename).length(); 10368d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project } catch (RuntimeException e) { 10378d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project Log.e(TAG, "get file length fail: " + e.getMessage()); 10388d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project mCurrentVideoFileLength = 0; 10398d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project } 1040d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang Log.v(TAG, "Setting current video filename: " 1041d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang + mCurrentVideoFilename); 1042b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project needToRegisterRecording = true; 1043b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorderRecording = false; 1044b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1045b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project releaseMediaRecorder(); 1046b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project updateRecordingIndicator(false); 1047b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mRecordingTimeView.setVisibility(View.GONE); 1048b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenTimeoutLong(); 1049b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 10509a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project if (needToRegisterRecording && mStorageStatus == STORAGE_STATUS_OK) { 10519a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project registerVideo(); 10529a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project } 1053b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1054b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCameraVideoFilename = null; 1055b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCameraVideoFileDescriptor = null; 1056b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1057b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1058b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void setScreenTimeoutSystemDefault() { 1059b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mHandler.removeMessages(CLEAR_SCREEN_DELAY); 1060b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project clearScreenOnFlag(); 1061b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1062b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1063b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void setScreenTimeoutLong() { 1064b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mHandler.removeMessages(CLEAR_SCREEN_DELAY); 1065b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenOnFlag(); 1066b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mHandler.sendEmptyMessageDelayed(CLEAR_SCREEN_DELAY, SCREEN_DELAY); 1067b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1068b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1069b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void setScreenTimeoutInfinite() { 1070b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mHandler.removeMessages(CLEAR_SCREEN_DELAY); 1071b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenOnFlag(); 1072b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1073b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1074b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void clearScreenOnFlag() { 1075b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Window w = getWindow(); 1076d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang final int flag = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; 1077d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang if ((w.getAttributes().flags & flag) != 0) { 1078d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang w.clearFlags(flag); 1079b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1080b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1081b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1082b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void setScreenOnFlag() { 1083b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Window w = getWindow(); 1084d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang final int flag = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; 1085d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang if ((w.getAttributes().flags & flag) == 0) { 1086d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang w.addFlags(flag); 1087b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1088b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1089b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 10909bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private void hideAlertAndStartPreview() { 10919bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang hideAlert(); 10929bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang initializeVideo(); 1093b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1094b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 10959bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private void hideAlertAndStartVideoRecording() { 10969bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang hideAlert(); 10979bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang startVideoRecording(); 1098b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1099b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 11009bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private void acquireVideoThumb() { 1101101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin Bitmap videoFrame = Util.createVideoThumbnail(mCurrentVideoFilename); 11029bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mThumbController.setData(mCurrentVideoUri, videoFrame); 1103de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 1104de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 11059bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private void showLastPictureButton() { 11069bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (!mIsVideoCaptureIntent) { 11079bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mLastPictureButton.setVisibility(View.VISIBLE); 1108de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 11099bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 1110de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 11119bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private void hideLastPictureButton() { 11129bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (!mIsVideoCaptureIntent) { 11139bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mLastPictureButton.setVisibility(View.INVISIBLE); 11149bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 1115de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 1116de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 11179bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private static ImageManager.DataLocation dataLocation() { 11189bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang return ImageManager.DataLocation.EXTERNAL; 1119de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 1120de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 11219bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private void updateLastVideo() { 1122101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin IImageList list = ImageManager.instance().allImages( 11239bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang this, 11249bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mContentResolver, 11259bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang dataLocation(), 11269bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang ImageManager.INCLUDE_VIDEOS, 11279bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang ImageManager.SORT_ASCENDING, 11289bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang ImageManager.CAMERA_IMAGE_BUCKET_ID); 11299bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang int count = list.getCount(); 11309bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (count > 0) { 1131d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang IImage image = list.getImageAt(count - 1); 11329bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang Uri uri = image.fullSizeImageUri(); 11339bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mThumbController.setData(uri, image.miniThumbBitmap()); 11349bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } else { 11359bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mThumbController.setData(null, null); 11369bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 11379bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang list.deactivate(); 1138b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1139b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 11409bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private static final String[] DATA_PATH_PROJECTION = new String[] { 11419bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang "_data" 11429bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang }; 11439bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 11449bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private String getDataPath(Uri uri) { 11459bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang Cursor c = null; 11469bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang try { 1147d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang c = mContentResolver.query(uri, DATA_PATH_PROJECTION, null, null, 1148d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang null); 11499bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (c != null && c.moveToFirst()) { 11509bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang return c.getString(0); 11519bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } else { 11529bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang return null; 11539bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 11549bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } finally { 11559bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (c != null) c.close(); 1156b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1157b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1158d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang 1159d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang private void updateRecordingTime() { 1160d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang if (!mMediaRecorderRecording) return; 1161d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang long now = SystemClock.uptimeMillis(); 1162d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang long delta = now - mRecordingStartTime; 1163d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang 1164d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // Starting a minute before reaching the max duration 1165d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // limit, we'll countdown the remaining time instead. 1166d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang boolean countdownRemainingTime = 1167d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang (delta >= MAX_RECORDING_DURATION_MS - 60000); 1168d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang 1169d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang if (countdownRemainingTime) { 1170d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang delta = Math.max(0, MAX_RECORDING_DURATION_MS - delta); 1171d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang } 1172d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang 1173d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang long seconds = (delta + 500) / 1000; // round to nearest 1174d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang long minutes = seconds / 60; 1175d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang long hours = minutes / 60; 1176d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang long remainderMinutes = minutes - (hours * 60); 1177d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang long remainderSeconds = seconds - (minutes * 60); 1178d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang 1179d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang String secondsString = Long.toString(remainderSeconds); 1180d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang if (secondsString.length() < 2) { 1181d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang secondsString = "0" + secondsString; 1182d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang } 1183d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang String minutesString = Long.toString(remainderMinutes); 1184d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang if (minutesString.length() < 2) { 1185d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang minutesString = "0" + minutesString; 1186d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang } 1187d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang String text = minutesString + ":" + secondsString; 1188d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang if (hours > 0) { 1189d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang String hoursString = Long.toString(hours); 1190d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang if (hoursString.length() < 2) { 1191d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang hoursString = "0" + hoursString; 1192d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang } 1193d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang text = hoursString + ":" + text; 1194d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang } 1195d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang mRecordingTimeView.setText(text); 1196d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang 1197d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang if (mRecordingTimeCountsDown != countdownRemainingTime) { 1198d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // Avoid setting the color on every update, do it only 1199d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // when it needs changing. 1200d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang 1201d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang mRecordingTimeCountsDown = countdownRemainingTime; 1202d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang 1203d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang int color = getResources().getColor( 1204d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang countdownRemainingTime 1205d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang ? R.color.recording_time_remaining_text 1206d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang : R.color.recording_time_elapsed_text); 1207d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang 1208d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang mRecordingTimeView.setTextColor(color); 1209d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang } 1210d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang 1211d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // Work around a limitation of the T-Mobile G1: The T-Mobile 1212d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // hardware blitter can't pixel-accurately scale and clip at the 1213d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // same time, and the SurfaceFlinger doesn't attempt to work around 1214d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // this limitation. In order to avoid visual corruption we must 1215d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // manually refresh the entire surface view when changing any 1216d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // overlapping view's contents. 1217d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang mVideoPreview.invalidate(); 1218d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang mHandler.sendEmptyMessageDelayed(UPDATE_RECORD_TIME, 1000); 1219d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang } 1220b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project} 1221