VideoCamera.java revision 23c51b794e95c201290e36737f379c4bb8eefeae
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 6923c51b794e95c201290e36737f379c4bb8eefeaeRay Chen/** 7023c51b794e95c201290e36737f379c4bb8eefeaeRay Chen * The Camcorder activity. 7123c51b794e95c201290e36737f379c4bb8eefeaeRay Chen */ 72b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Projectpublic class VideoCamera extends Activity implements View.OnClickListener, 73d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang ShutterButton.OnShutterButtonListener, SurfaceHolder.Callback, 74d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang MediaRecorder.OnErrorListener, MediaRecorder.OnInfoListener { 75b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 76b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final String TAG = "videocamera"; 77b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 78b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final int CLEAR_SCREEN_DELAY = 4; 79b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final int UPDATE_RECORD_TIME = 5; 80b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 81b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final int SCREEN_DELAY = 2 * 60 * 1000; 82b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 83b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final long NO_STORAGE_ERROR = -1L; 84b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final long CANNOT_STAT_ERROR = -2L; 85b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final long LOW_STORAGE_THRESHOLD = 512L * 1024L; 86e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project private static final long SHARE_FILE_LENGTH_LIMIT = 3L * 1024L * 1024L; 87b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 889a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project private static final int STORAGE_STATUS_OK = 0; 899a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project private static final int STORAGE_STATUS_LOW = 1; 909a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project private static final int STORAGE_STATUS_NONE = 2; 919a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project 92b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public static final int MENU_SETTINGS = 6; 93b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public static final int MENU_GALLERY_PHOTOS = 7; 94b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public static final int MENU_GALLERY_VIDEOS = 8; 95b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public static final int MENU_SAVE_GALLERY_PHOTO = 34; 96b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public static final int MENU_SAVE_PLAY_VIDEO = 35; 97b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public static final int MENU_SAVE_SELECT_VIDEO = 36; 98b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public static final int MENU_SAVE_NEW_VIDEO = 37; 99b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 100b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project SharedPreferences mPreferences; 101b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 102b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static final float VIDEO_ASPECT_RATIO = 176.0f / 144.0f; 103b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project VideoPreview mVideoPreview; 104b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project SurfaceHolder mSurfaceHolder = null; 105b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project ImageView mVideoFrame; 1069bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 1079bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private boolean mIsVideoCaptureIntent; 1089bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // mLastPictureButton and mThumbController 1099bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // are non-null only if isVideoCaptureIntent() is true; 110de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project private ImageView mLastPictureButton; 1119bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private ThumbnailController mThumbController; 112b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1138d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project private static final int MAX_RECORDING_DURATION_MS = 10 * 60 * 1000; 1148d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project 1159a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project private int mStorageStatus = STORAGE_STATUS_OK; 1169a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project 117b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private MediaRecorder mMediaRecorder; 118b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private boolean mMediaRecorderRecording = false; 119b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private long mRecordingStartTime; 120b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // The video file that the hardware camera is about to record into 121b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // (or is recording into.) 122b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private String mCameraVideoFilename; 123b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private FileDescriptor mCameraVideoFileDescriptor; 124b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 125b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // The video file that has already been recorded, and that is being 126b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // examined by the user. 127b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private String mCurrentVideoFilename; 1288d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project private long mCurrentVideoFileLength = 0L; 129b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private Uri mCurrentVideoUri; 130b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private ContentValues mCurrentVideoValues; 131b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 132b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project boolean mPausing = false; 133b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 134d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang private ContentResolver mContentResolver; 135b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 136b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int mCurrentZoomIndex = 0; 137b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 138b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private ShutterButton mShutterButton; 139b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private TextView mRecordingTimeView; 1408d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project private boolean mRecordingTimeCountsDown = false; 141b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 142b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project ArrayList<MenuItem> mGalleryItems = new ArrayList<MenuItem>(); 143b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 144b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project View mPostPictureAlert; 145b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project LocationManager mLocationManager = null; 146b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 147b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private Handler mHandler = new MainHandler(); 148b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 149d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // This Handler is used to post message back onto the main thread of the 150d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // application 151b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private class MainHandler extends Handler { 152b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 153b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void handleMessage(Message msg) { 154b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project switch (msg.what) { 155b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 156b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case CLEAR_SCREEN_DELAY: { 157b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project clearScreenOnFlag(); 158b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 159b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 160b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 161b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case UPDATE_RECORD_TIME: { 162d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang updateRecordingTime(); 163b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 164b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 165b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 166b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project default: 167b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Unhandled message: " + msg.what); 168b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 169b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 170b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 171b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project }; 172b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 173b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 174b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 175b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void onReceive(Context context, Intent intent) { 176b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String action = intent.getAction(); 177b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (action.equals(Intent.ACTION_MEDIA_EJECT)) { 1789a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project updateAndShowStorageHint(false); 179b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project stopVideoRecording(); 180b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project initializeVideo(); 181b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else if (action.equals(Intent.ACTION_MEDIA_MOUNTED)) { 1829a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project updateAndShowStorageHint(true); 183b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project initializeVideo(); 184b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else if (action.equals(Intent.ACTION_MEDIA_UNMOUNTED)) { 185b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // SD card unavailable 1869a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project // handled in ACTION_MEDIA_EJECT 187b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else if (action.equals(Intent.ACTION_MEDIA_SCANNER_STARTED)) { 188d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang Toast.makeText(VideoCamera.this, 189d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang getResources().getString(R.string.wait), 5000); 190b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else if (action.equals(Intent.ACTION_MEDIA_SCANNER_FINISHED)) { 1919a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project updateAndShowStorageHint(true); 192b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 193b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 194b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project }; 195b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 196d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang private static String createName(long dateTaken) { 197b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return DateFormat.format("yyyy-MM-dd kk.mm.ss", dateTaken).toString(); 198b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 199b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 200b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project /** Called with the activity is first created. */ 201b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 202b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void onCreate(Bundle icicle) { 203b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project super.onCreate(icicle); 204b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 205d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang mLocationManager = (LocationManager) getSystemService( 206d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang Context.LOCATION_SERVICE); 207b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 208b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mPreferences = PreferenceManager.getDefaultSharedPreferences(this); 209b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mContentResolver = getContentResolver(); 210b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 211b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project //setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT); 212b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project requestWindowFeature(Window.FEATURE_PROGRESS); 213b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setContentView(R.layout.video_camera); 214b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 215b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mVideoPreview = (VideoPreview) findViewById(R.id.camera_preview); 216b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mVideoPreview.setAspectRatio(VIDEO_ASPECT_RATIO); 217b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 218b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // don't set mSurfaceHolder here. We have it set ONLY within 219b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // surfaceCreated / surfaceDestroyed, other parts of the code 220b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // assume that when it is set, the surface is also set. 221b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project SurfaceHolder holder = mVideoPreview.getHolder(); 222b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project holder.addCallback(this); 223b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 224b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 225b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mPostPictureAlert = findViewById(R.id.post_picture_panel); 226b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 227b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int[] ids = new int[]{R.id.play, R.id.share, R.id.discard, 228b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project R.id.cancel, R.id.attach}; 229b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project for (int id : ids) { 230b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project findViewById(id).setOnClickListener(this); 231b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 232b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 233b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mShutterButton = (ShutterButton) findViewById(R.id.shutter_button); 234b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mShutterButton.setOnShutterButtonListener(this); 235b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mRecordingTimeView = (TextView) findViewById(R.id.recording_time); 236b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mVideoFrame = (ImageView) findViewById(R.id.video_frame); 2379bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mIsVideoCaptureIntent = isVideoCaptureIntent(); 2389bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (!mIsVideoCaptureIntent) { 239d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang mLastPictureButton = (ImageView) findViewById( 240d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang R.id.last_picture_button); 2419bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mLastPictureButton.setOnClickListener(this); 242d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang Drawable frame = getResources().getDrawable( 243d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang R.drawable.frame_thumbnail); 2449bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mThumbController = new ThumbnailController(mLastPictureButton, 2459bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang frame, mContentResolver); 2469bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mThumbController.loadData(ImageManager.getLastVideoThumbPath()); 2479bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 248b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 249b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 250e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project private void startShareVideoActivity() { 2518d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project if (mCurrentVideoFileLength > SHARE_FILE_LENGTH_LIMIT) { 252e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project Toast.makeText(VideoCamera.this, 253e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project R.string.too_large_to_attach, Toast.LENGTH_LONG).show(); 254e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project return; 255e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project } 256e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project Intent intent = new Intent(); 257e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project intent.setAction(Intent.ACTION_SEND); 258e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project intent.setType("video/3gpp"); 259e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project intent.putExtra(Intent.EXTRA_STREAM, mCurrentVideoUri); 260e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project try { 261d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang startActivity(Intent.createChooser( 262d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang intent, getText(R.string.sendVideo))); 263e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project } catch (android.content.ActivityNotFoundException ex) { 264d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang Toast.makeText(VideoCamera.this, R.string.no_way_to_share_video, 265d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang Toast.LENGTH_SHORT).show(); 266e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project } 267e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project } 268e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project 269b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void onClick(View v) { 270b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project switch (v.getId()) { 271b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 272b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case R.id.gallery: 273b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project MenuHelper.gotoCameraVideoGallery(this); 274b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 275b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 276b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case R.id.attach: 277b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project doReturnToCaller(true); 278b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 279b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 280b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case R.id.cancel: 281b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project doReturnToCaller(false); 282b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 283b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 284b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case R.id.discard: { 2857638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen Runnable deleteCallback = new Runnable() { 2867638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen public void run() { 2877638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen discardCurrentVideoAndStartPreview(); 2887638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen } 2897638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen }; 2907638a541959f3f371b9998844a0bbef2df4aa3eeRay Chen MenuHelper.deleteVideo(this, deleteCallback); 291b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 292b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 293b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 294b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case R.id.share: { 295e3f4516c2154539cb5778ef061abf8a0ccf90a5eThe Android Open Source Project startShareVideoActivity(); 296b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 297b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 298b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 299b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case R.id.play: { 300b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project doPlayCurrentVideo(); 301b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 302b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 303de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 304de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project case R.id.last_picture_button: { 3059bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang stopVideoRecordingAndShowAlert(); 306de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project break; 307de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 308b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 309b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 310b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 311b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void onShutterButtonFocus(ShutterButton button, boolean pressed) { 312de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project // Do nothing (everything happens in onShutterButtonClick). 313de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 314de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 315de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project public void onShutterButtonClick(ShutterButton button) { 316b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project switch (button.getId()) { 317b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case R.id.shutter_button: 318de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project if (mMediaRecorderRecording) { 3199bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (mIsVideoCaptureIntent) { 320de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project stopVideoRecordingAndShowAlert(); 321b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 3229bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang stopVideoRecordingAndGetThumbnail(); 3239bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang initializeVideo(); 3249bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 3259bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } else if (isAlertVisible()) { 3269bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (mIsVideoCaptureIntent) { 3279bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang discardCurrentVideoAndStartPreview(); 3289bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } else { 3299bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang hideAlertAndStartVideoRecording(); 330b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 331de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } else { 332de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project startVideoRecording(); 333b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 334b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 335b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 336b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 337b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 338b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void doPlayCurrentVideo() { 339b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.e(TAG, "Playing current video: " + mCurrentVideoUri); 340b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Intent intent = new Intent(Intent.ACTION_VIEW, mCurrentVideoUri); 341b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project try { 342b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project startActivity(intent); 343b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } catch (android.content.ActivityNotFoundException ex) { 344b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.e(TAG, "Couldn't view video " + mCurrentVideoUri, ex); 345b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 346b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 347b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 348b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void discardCurrentVideoAndStartPreview() { 349b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project deleteCurrentVideo(); 3509bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang hideAlertAndStartPreview(); 351b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 352b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 353b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private OnScreenHint mStorageHint; 354b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 3559a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project private void updateAndShowStorageHint(boolean mayHaveSd) { 3569a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project mStorageStatus = getStorageStatus(mayHaveSd); 3579a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project showStorageHint(); 3589a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project } 3599a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project 3609a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project private void showStorageHint() { 361b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String errorMessage = null; 3629a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project switch (mStorageStatus) { 3639a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project case STORAGE_STATUS_NONE: 364b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project errorMessage = getString(R.string.no_storage); 3659a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project break; 3669a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project case STORAGE_STATUS_LOW: 367b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project errorMessage = getString(R.string.spaceIsLow_content); 368b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 369b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (errorMessage != null) { 370b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mStorageHint == null) { 371b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mStorageHint = OnScreenHint.makeText(this, errorMessage); 372b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 373b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mStorageHint.setText(errorMessage); 374b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 375b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mStorageHint.show(); 376b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else if (mStorageHint != null) { 377b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mStorageHint.cancel(); 378b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mStorageHint = null; 379b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 380b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 381b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 3829a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project private int getStorageStatus(boolean mayHaveSd) { 3839a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project long remaining = mayHaveSd ? getAvailableStorage() : NO_STORAGE_ERROR; 3849a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project if (remaining == NO_STORAGE_ERROR) { 3859a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project return STORAGE_STATUS_NONE; 3869a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project } 3879a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project return remaining < LOW_STORAGE_THRESHOLD 3889a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project ? STORAGE_STATUS_LOW : STORAGE_STATUS_OK; 3899a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project } 3909a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project 391b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 392b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void onResume() { 393b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project super.onResume(); 394b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 395b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenTimeoutLong(); 396b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 397b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mPausing = false; 398b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 399b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // install an intent filter to receive SD card related events. 400d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang IntentFilter intentFilter = 401d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang new IntentFilter(Intent.ACTION_MEDIA_MOUNTED); 402b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project intentFilter.addAction(Intent.ACTION_MEDIA_EJECT); 403b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project intentFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED); 404b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_STARTED); 405b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED); 406b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project intentFilter.addDataScheme("file"); 407b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project registerReceiver(mReceiver, intentFilter); 4089a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project mStorageStatus = getStorageStatus(true); 4099a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project 4109a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project mHandler.postDelayed(new Runnable() { 4119a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project public void run() { 4129a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project showStorageHint(); 4139a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project } 4149a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project }, 200); 415b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 4169bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang initializeVideo(); 417b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 418b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 419b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 420b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void onStop() { 421b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenTimeoutSystemDefault(); 422b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project super.onStop(); 423b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 424b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 425b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 426b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project protected void onPause() { 427b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project super.onPause(); 428b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 4299bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // This is similar to what mShutterButton.performClick() does, 4309bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // but not quite the same. 4319bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (mMediaRecorderRecording) { 4329bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (mIsVideoCaptureIntent) { 4339bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang stopVideoRecordingAndShowAlert(); 4349bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } else { 4359bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang stopVideoRecordingAndGetThumbnail(); 4369bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 4379bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } else { 4389bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang stopVideoRecording(); 4399bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 440b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 441b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mPausing = true; 442b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 4439c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project unregisterReceiver(mReceiver); 444b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenTimeoutSystemDefault(); 445b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 4469bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (!mIsVideoCaptureIntent) { 4479bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mThumbController.storeData(ImageManager.getLastVideoThumbPath()); 4489bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 449095afa19556bf550262e3cccb9edacc04e6f726aOwen Lin 450b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mStorageHint != null) { 451b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mStorageHint.cancel(); 452b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mStorageHint = null; 453b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 454b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 455b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 456b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 457b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public boolean onKeyDown(int keyCode, KeyEvent event) { 458b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenTimeoutLong(); 459b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 460b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project switch (keyCode) { 461b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case KeyEvent.KEYCODE_BACK: 462b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mMediaRecorderRecording) { 463de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mShutterButton.performClick(); 464b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 465d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang } else if (isAlertVisible()) { 4669bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang hideAlertAndStartPreview(); 467b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 468b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 469b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 470b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case KeyEvent.KEYCODE_CAMERA: 471b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (event.getRepeatCount() == 0) { 472de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mShutterButton.performClick(); 473b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 474b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 475de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project break; 476b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case KeyEvent.KEYCODE_DPAD_CENTER: 477b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (event.getRepeatCount() == 0) { 478de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mShutterButton.performClick(); 479de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project return true; 480b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 481b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 482b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case KeyEvent.KEYCODE_MENU: 483b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mMediaRecorderRecording) { 484de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mShutterButton.performClick(); 485b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 486b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 487b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project break; 488b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 489b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 490b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return super.onKeyDown(keyCode, event); 491b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 492b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 493b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 494b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public boolean onKeyUp(int keyCode, KeyEvent event) { 495b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project switch(keyCode) { 496b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project case KeyEvent.KEYCODE_CAMERA: 497b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mShutterButton.setPressed(false); 498b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 499b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 500b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return super.onKeyUp(keyCode, event); 501b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 502b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 503b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 504314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber if (mPausing) { 505314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber // We're pausing, the screen is off and we already stopped 506314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber // video recording. We don't want to start the camera again 507314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber // in this case in order to conserve power. 508314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber // The fact that surfaceChanged is called _after_ an onPause appears 509314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber // to be legitimate since in that case the lockscreen always returns 510314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber // to portrait orientation possibly triggering the notification. 511314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber return; 512314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber } 513314f9a79f1395af71f2c2bb629435bfda07a55aeAndreas Huber 514b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project stopVideoRecording(); 515b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project initializeVideo(); 516b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 517b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 518b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void surfaceCreated(SurfaceHolder holder) { 519b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mSurfaceHolder = holder; 520b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 521b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 522b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void surfaceDestroyed(SurfaceHolder holder) { 523b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mSurfaceHolder = null; 524b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 525b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 526b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project void gotoGallery() { 527b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project MenuHelper.gotoCameraVideoGallery(this); 528b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 529b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 530b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 531b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public boolean onPrepareOptionsMenu(Menu menu) { 532b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project super.onPrepareOptionsMenu(menu); 533b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 534b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project for (int i = 1; i <= MenuHelper.MENU_ITEM_MAX; i++) { 535b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (i != MenuHelper.GENERIC_ITEM) { 536b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project menu.setGroupVisible(i, false); 537b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 538b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 539b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 540b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project menu.setGroupVisible(MenuHelper.VIDEO_MODE_ITEM, true); 541b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 542b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 543b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 544b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project @Override 545b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public boolean onCreateOptionsMenu(Menu menu) { 546b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project super.onCreateOptionsMenu(menu); 547b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 5489bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (mIsVideoCaptureIntent) { 549b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // No options menu for attach mode. 550b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return false; 551b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 552b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project addBaseMenuItems(menu); 553d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang int menuFlags = MenuHelper.INCLUDE_ALL 554d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang & ~MenuHelper.INCLUDE_ROTATE_MENU 555095afa19556bf550262e3cccb9edacc04e6f726aOwen Lin & ~MenuHelper.INCLUDE_DETAILS_MENU; 556b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project MenuHelper.addImageMenuItems( 557b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project menu, 558095afa19556bf550262e3cccb9edacc04e6f726aOwen Lin menuFlags, 559b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project false, 560b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project VideoCamera.this, 56123c51b794e95c201290e36737f379c4bb8eefeaeRay Chen mHandler, 562b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // Handler for deletion 563b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project new Runnable() { 564b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void run() { 565b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // What do we do here? 566b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // mContentResolver.delete(uri, null, null); 567b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 568b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project }, 569b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project new MenuHelper.MenuInvoker() { 570b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void run(final MenuHelper.MenuCallback cb) { 571b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 572b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project }); 573b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 574d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang MenuItem gallery = menu.add(MenuHelper.IMAGE_SAVING_ITEM, 575d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang MENU_SAVE_GALLERY_PHOTO, 0, 576d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang R.string.camera_gallery_photos_text) 577d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang .setOnMenuItemClickListener( 578d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang new MenuItem.OnMenuItemClickListener() { 579d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang public boolean onMenuItemClick(MenuItem item) { 580d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang gotoGallery(); 581d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang return true; 582d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang } 583d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang }); 584b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project gallery.setIcon(android.R.drawable.ic_menu_gallery); 585b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 586b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 587b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 588b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 589b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private boolean isVideoCaptureIntent() { 590b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String action = getIntent().getAction(); 591b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return (MediaStore.ACTION_VIDEO_CAPTURE.equals(action)); 592b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 593b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 594b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void doReturnToCaller(boolean success) { 595b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Intent resultIntent = new Intent(); 596b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int resultCode; 597b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (success) { 598b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project resultCode = RESULT_OK; 599b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project resultIntent.setData(mCurrentVideoUri); 600b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 601b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project resultCode = RESULT_CANCELED; 602b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 603b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setResult(resultCode, resultIntent); 604b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project finish(); 605b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 606b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 607b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project /** 608b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * Returns 609b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project * @return number of bytes available, or an ERROR code. 610b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project */ 611b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private static long getAvailableStorage() { 612b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project try { 613b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (!ImageManager.hasStorage()) { 614b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return NO_STORAGE_ERROR; 615b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 616d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang String storageDirectory = Environment 617d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang .getExternalStorageDirectory().toString(); 618b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project StatFs stat = new StatFs(storageDirectory); 619d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang return ((long) stat.getAvailableBlocks() 620d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang * (long) stat.getBlockSize()); 621b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 62223c51b794e95c201290e36737f379c4bb8eefeaeRay Chen } catch (RuntimeException ex) { 623b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // if we can't stat the filesystem then we don't know how many 624b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // free bytes exist. It might be zero but just leave it 625b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // blank since we really don't know. 626b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return CANNOT_STAT_ERROR; 627b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 628b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 629b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 630b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void cleanupEmptyFile() { 631b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mCameraVideoFilename != null) { 632b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project File f = new File(mCameraVideoFilename); 633b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (f.length() == 0 && f.delete()) { 634b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Empty video file deleted: " + mCameraVideoFilename); 635b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCameraVideoFilename = null; 636b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 637b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 638b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 639b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 6409bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // initializeVideo() starts preview and prepare media recorder. 641b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // Returns false if initializeVideo fails 642b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private boolean initializeVideo() { 643b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "initializeVideo"); 6449bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 6459bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // We will call initializeVideo() again when the alert is hidden. 64623c51b794e95c201290e36737f379c4bb8eefeaeRay Chen if (isAlertVisible()) { 64723c51b794e95c201290e36737f379c4bb8eefeaeRay Chen return false; 64823c51b794e95c201290e36737f379c4bb8eefeaeRay Chen } 6499bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 650b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Intent intent = getIntent(); 651b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Bundle myExtras = intent.getExtras(); 652b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 6539bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (mIsVideoCaptureIntent && myExtras != null) { 654b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Uri saveUri = (Uri) myExtras.getParcelable(MediaStore.EXTRA_OUTPUT); 655b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (saveUri != null) { 656b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project try { 657b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCameraVideoFileDescriptor = mContentResolver. 658b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project openFileDescriptor(saveUri, "rw").getFileDescriptor(); 659b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoUri = saveUri; 660d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang } catch (java.io.FileNotFoundException ex) { 661b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // invalid uri 662b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.e(TAG, ex.toString()); 663b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 664b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 665b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 666b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project releaseMediaRecorder(); 667b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 668b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mSurfaceHolder == null) { 669b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "SurfaceHolder is null"); 670b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return false; 671b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 672b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 673b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder = new MediaRecorder(); 674b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 675d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); 676b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); 677b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); 678b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 6798d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project mMediaRecorder.setMaxDuration(MAX_RECORDING_DURATION_MS); 6808d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project 6819a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project if (mStorageStatus != STORAGE_STATUS_OK) { 682b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setOutputFile("/dev/null"); 683b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 684d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // We try Uri in intent first. If it doesn't work, use our own 685d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // instead. 686b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mCameraVideoFileDescriptor != null) { 687b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setOutputFile(mCameraVideoFileDescriptor); 688b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 689b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project createVideoPath(); 690b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setOutputFile(mCameraVideoFilename); 691b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 692b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 693b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 694d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang boolean videoQualityHigh = getBooleanPreference( 695d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang CameraSettings.KEY_VIDEO_QUALITY, 696b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project CameraSettings.DEFAULT_VIDEO_QUALITY_VALUE); 697b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 698b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (intent.hasExtra(MediaStore.EXTRA_VIDEO_QUALITY)) { 699d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang int extraVideoQuality = intent.getIntExtra( 700d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang MediaStore.EXTRA_VIDEO_QUALITY, 0); 701b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project videoQualityHigh = (extraVideoQuality > 0); 702b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 703b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 704b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // Use the same frame rate for both, since internally 705b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // if the frame rate is too large, it can cause camera to become 706b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // unstable. We need to fix the MediaRecorder to disable the support 707b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // of setting frame rate for now. 708b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setVideoFrameRate(20); 709b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (videoQualityHigh) { 710d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang mMediaRecorder.setVideoSize(352, 288); 711b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } else { 712d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang mMediaRecorder.setVideoSize(176, 144); 713b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 714b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263); 715d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); 716b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface()); 717de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 718de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project long remaining = getAvailableStorage(); 719de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project // remaining >= LOW_STORAGE_THRESHOLD at this point, reserve a quarter 720d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // of that to make it more likely that recording can complete 721d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // successfully. 722de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project try { 723d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang mMediaRecorder.setMaxFileSize(remaining - 724d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang LOW_STORAGE_THRESHOLD / 4); 725de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } catch (RuntimeException exception) { 726de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project // We are going to ignore failure of setMaxFileSize here, as 727de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project // a) The composer selected may simply not support it, or 728de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project // b) The underlying media framework may not handle 64-bit range 729de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project // on the size restriction. 730de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 731de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 732b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project try { 733b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.prepare(); 734b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } catch (IOException exception) { 735b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.e(TAG, "prepare failed for " + mCameraVideoFilename); 736b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project releaseMediaRecorder(); 737b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // TODO: add more exception handling logic here 738b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return false; 739b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 740b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorderRecording = false; 7419bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 7429bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (!mIsVideoCaptureIntent && !mThumbController.isUriValid()) { 7439bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang updateLastVideo(); 7449bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 7459bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 7469bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (!mIsVideoCaptureIntent) { 7479bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mThumbController.updateDisplayIfNeeded(); 7489bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 7499bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 750b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return true; 751b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 752b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 753b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void releaseMediaRecorder() { 754b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Releasing media recorder."); 755b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mMediaRecorder != null) { 756b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project cleanupEmptyFile(); 757b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.reset(); 758b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.release(); 759b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder = null; 760b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 761b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 762b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 763b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private int getIntPreference(String key, int defaultValue) { 764b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String s = mPreferences.getString(key, ""); 765b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int result = defaultValue; 766b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project try { 767b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project result = Integer.parseInt(s); 768b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } catch (NumberFormatException e) { 769b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // Ignore, result is already the default value. 770b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 771b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return result; 772b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 773b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 774b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private boolean getBooleanPreference(String key, boolean defaultValue) { 775b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return getIntPreference(key, defaultValue ? 1 : 0) != 0; 776b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 777b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 778b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void createVideoPath() { 779b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project long dateTaken = System.currentTimeMillis(); 780b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String title = createName(dateTaken); 781b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String displayName = title + ".3gp"; // Used when emailing. 782b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String cameraDirPath = ImageManager.CAMERA_IMAGE_BUCKET_NAME; 783b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project File cameraDir = new File(cameraDirPath); 784b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project cameraDir.mkdirs(); 785b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project SimpleDateFormat dateFormat = new SimpleDateFormat( 786b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project getString(R.string.video_file_name_format)); 787b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Date date = new Date(dateTaken); 788b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String filepart = dateFormat.format(date); 789b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project String filename = cameraDirPath + "/" + filepart + ".3gp"; 790b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project ContentValues values = new ContentValues(7); 791b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project values.put(Video.Media.TITLE, title); 792b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project values.put(Video.Media.DISPLAY_NAME, displayName); 793b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project values.put(Video.Media.DESCRIPTION, ""); 794b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project values.put(Video.Media.DATE_TAKEN, dateTaken); 795b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project values.put(Video.Media.MIME_TYPE, "video/3gpp"); 796b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project values.put(Video.Media.DATA, filename); 797b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCameraVideoFilename = filename; 798b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Current camera video filename: " + mCameraVideoFilename); 799b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoValues = values; 800b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 801b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 802b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void registerVideo() { 803b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mCameraVideoFileDescriptor == null) { 804b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Uri videoTable = Uri.parse("content://media/external/video/media"); 805b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoUri = mContentResolver.insert(videoTable, 806b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoValues); 807b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Current video URI: " + mCurrentVideoUri); 808b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 809b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoValues = null; 810b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 811b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 812b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void deleteCurrentVideo() { 813b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mCurrentVideoFilename != null) { 814b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project deleteVideoFile(mCurrentVideoFilename); 815b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoFilename = null; 816b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 817b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mCurrentVideoUri != null) { 818b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mContentResolver.delete(mCurrentVideoUri, null, null); 819b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoUri = null; 820b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 821de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project updateAndShowStorageHint(true); 822b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 823b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 824b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void deleteVideoFile(String fileName) { 825b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Deleting video " + fileName); 826b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project File f = new File(fileName); 827d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang if (!f.delete()) { 828b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Could not delete " + fileName); 829b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 830b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 831b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 832b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void addBaseMenuItems(Menu menu) { 833b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project MenuHelper.addSwitchModeMenuItem(menu, this, false); 834b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project { 835d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang MenuItem gallery = menu.add(MenuHelper.IMAGE_MODE_ITEM, 836d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang MENU_GALLERY_PHOTOS, 0, R.string.camera_gallery_photos_text) 837d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang .setOnMenuItemClickListener(new OnMenuItemClickListener() { 838d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang public boolean onMenuItemClick(MenuItem item) { 839d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang gotoGallery(); 840d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang return true; 841d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang } 842d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang }); 843b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project gallery.setIcon(android.R.drawable.ic_menu_gallery); 844b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mGalleryItems.add(gallery); 845b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 846b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project { 847d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang MenuItem gallery = menu.add(MenuHelper.VIDEO_MODE_ITEM, 848d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang MENU_GALLERY_VIDEOS, 0, R.string.camera_gallery_photos_text) 849d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang .setOnMenuItemClickListener(new OnMenuItemClickListener() { 850d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang public boolean onMenuItemClick(MenuItem item) { 851d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang gotoGallery(); 852d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang return true; 853d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang } 854d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang }); 855b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project gallery.setIcon(android.R.drawable.ic_menu_gallery); 856b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mGalleryItems.add(gallery); 857b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 858b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 859d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang MenuItem item = menu.add(MenuHelper.GENERIC_ITEM, MENU_SETTINGS, 0, 860d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang R.string.settings) 861d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang .setOnMenuItemClickListener(new OnMenuItemClickListener() { 862d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang public boolean onMenuItemClick(MenuItem item) { 863d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang Intent intent = new Intent(); 864d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang intent.setClass(VideoCamera.this, CameraSettings.class); 865d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang startActivity(intent); 866d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang return true; 867d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang } 868d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang }); 869b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project item.setIcon(android.R.drawable.ic_menu_preferences); 870b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 871b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 872b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // from MediaRecorder.OnErrorListener 873b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project public void onError(MediaRecorder mr, int what, int extra) { 874b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (what == MediaRecorder.MEDIA_RECORDER_ERROR_UNKNOWN) { 875b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // We may have run out of space on the sdcard. 876b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project stopVideoRecording(); 8779a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project updateAndShowStorageHint(true); 878b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 879b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 880b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 8818d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project // from MediaRecorder.OnInfoListener 8828d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project public void onInfo(MediaRecorder mr, int what, int extra) { 8838d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) { 884de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mShutterButton.performClick(); 885d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang } else if (what 886d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang == MediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED) { 887de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mShutterButton.performClick(); 888de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project updateAndShowStorageHint(true); 8898d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project } 8908d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project } 8918d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project 8929c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project /* 8939c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project * Make sure we're not recording music playing in the background, ask 8949c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project * the MediaPlaybackService to pause playback. 8959c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project */ 8969c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project private void pauseAudioPlayback() { 8979c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project // Shamelessly copied from MediaPlaybackService.java, which 8989c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project // should be public, but isn't. 8999c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project Intent i = new Intent("com.android.music.musicservicecommand"); 9009c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project i.putExtra("command", "pause"); 9019c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project 9029c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project sendBroadcast(i); 9039c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project } 9049c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project 905b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void startVideoRecording() { 906b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "startVideoRecording"); 907b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (!mMediaRecorderRecording) { 908b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 9099a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project if (mStorageStatus != STORAGE_STATUS_OK) { 910b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "Storage issue, ignore the start request"); 911b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return; 912b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 913b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 914b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project // Check mMediaRecorder to see whether it is initialized or not. 915d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang if (mMediaRecorder == null && initializeVideo() == false) { 916b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.e(TAG, "Initialize video (MediaRecorder) failed."); 917b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return; 918b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 919b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 9209c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project pauseAudioPlayback(); 9219c9be2eb4a86fc3468dbba1ec5f7bfdb37d22c74The Android Open Source Project 922b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project try { 923b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setOnErrorListener(this); 9248d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project mMediaRecorder.setOnInfoListener(this); 925b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.start(); // Recording is now started 926b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } catch (RuntimeException e) { 927b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.e(TAG, "Could not start media recorder. ", e); 928b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return; 929b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 930b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorderRecording = true; 931b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mRecordingStartTime = SystemClock.uptimeMillis(); 932b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project updateRecordingIndicator(true); 933b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mRecordingTimeView.setText(""); 934b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mRecordingTimeView.setVisibility(View.VISIBLE); 935b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mHandler.sendEmptyMessage(UPDATE_RECORD_TIME); 936b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenTimeoutInfinite(); 937de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project hideLastPictureButton(); 938b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 939b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 940b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 941b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void updateRecordingIndicator(boolean showRecording) { 942d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang int drawableId = showRecording 943d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang ? R.drawable.ic_camera_bar_indicator_record 944d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang : R.drawable.ic_camera_indicator_video; 945b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Drawable drawable = getResources().getDrawable(drawableId); 946b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mShutterButton.setImageDrawable(drawable); 947b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 948b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 9499bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private void stopVideoRecordingAndGetThumbnail() { 9509bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang stopVideoRecording(); 9519bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang acquireVideoThumb(); 952b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 953b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 954de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project private void stopVideoRecordingAndShowAlert() { 955de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project stopVideoRecording(); 9569bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang showAlert(); 957de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 958de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 9599bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private void showAlert() { 960b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int[] pickIds = {R.id.attach, R.id.cancel}; 961b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int[] normalIds = {R.id.gallery, R.id.share, R.id.discard}; 962b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int[] alwaysOnIds = {R.id.play}; 963b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int[] hideIds = pickIds; 964b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project int[] connectIds = normalIds; 9659bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (mIsVideoCaptureIntent) { 966b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project hideIds = normalIds; 967b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project connectIds = pickIds; 968b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 969d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang for (int id : hideIds) { 970b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mPostPictureAlert.findViewById(id).setVisibility(View.GONE); 971b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 9728d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project ActionMenuButton shareButton = 9738d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project (ActionMenuButton) mPostPictureAlert.findViewById(R.id.share); 9748d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project shareButton.setRestricted( 9758d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project mCurrentVideoFileLength > SHARE_FILE_LENGTH_LIMIT); 976b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project connectAndFadeIn(connectIds); 977b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project connectAndFadeIn(alwaysOnIds); 978de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project hideLastPictureButton(); 979b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mPostPictureAlert.setVisibility(View.VISIBLE); 9809bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 9819bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // There are two cases we are here: 9829bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // (1) We are in a capture video intent, and we are reviewing the video 983095afa19556bf550262e3cccb9edacc04e6f726aOwen Lin // we just taken. 9849bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // (2) The thumbnail button is clicked: we review the video associated 9859bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // with the thumbnail. 9869bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // For the second case, we copy the associated URI and filename to 9879bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // mCurrentVideoUri and mCurrentVideoFilename, so the video frame shown 9889bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang // and the target for actions (play, delete, ...) will be correct. 9899bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 9909bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (!mIsVideoCaptureIntent) { 9919bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mCurrentVideoUri = mThumbController.getUri(); 9929bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mCurrentVideoFilename = getDataPath(mCurrentVideoUri); 9939bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 9949bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 9959bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang String path = mCurrentVideoFilename; 9969bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (path != null) { 997101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin Bitmap videoFrame = Util.createVideoThumbnail(path); 9989bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mVideoFrame.setImageBitmap(videoFrame); 9999bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mVideoFrame.setVisibility(View.VISIBLE); 10009bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 1001b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1002b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 10039bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private void hideAlert() { 1004de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mVideoFrame.setVisibility(View.INVISIBLE); 1005de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project mPostPictureAlert.setVisibility(View.INVISIBLE); 1006de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project showLastPictureButton(); 1007de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 1008de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 1009b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void connectAndFadeIn(int[] connectIds) { 1010d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang for (int id : connectIds) { 1011b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project View view = mPostPictureAlert.findViewById(id); 1012b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project view.setOnClickListener(this); 1013b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Animation animation = new AlphaAnimation(0F, 1F); 1014b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project animation.setDuration(500); 10159bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang view.startAnimation(animation); 1016b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1017b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1018b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 10199bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private boolean isAlertVisible() { 1020b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project return mPostPictureAlert.getVisibility() == View.VISIBLE; 1021b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1022b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1023b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void stopVideoRecording() { 1024b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.v(TAG, "stopVideoRecording"); 1025b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project boolean needToRegisterRecording = false; 1026b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mMediaRecorderRecording || mMediaRecorder != null) { 1027b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project if (mMediaRecorderRecording && mMediaRecorder != null) { 1028b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project try { 1029b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.setOnErrorListener(null); 10308d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project mMediaRecorder.setOnInfoListener(null); 1031b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorder.stop(); 1032b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } catch (RuntimeException e) { 1033b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Log.e(TAG, "stop fail: " + e.getMessage()); 1034b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 10358d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project 1036b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCurrentVideoFilename = mCameraVideoFilename; 10378d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project try { 1038d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang mCurrentVideoFileLength = 1039d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang new File(mCurrentVideoFilename).length(); 10408d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project } catch (RuntimeException e) { 10418d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project Log.e(TAG, "get file length fail: " + e.getMessage()); 10428d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project mCurrentVideoFileLength = 0; 10438d0dd0e2ee9a9f8d729ed96597102777cf14701fThe Android Open Source Project } 1044d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang Log.v(TAG, "Setting current video filename: " 1045d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang + mCurrentVideoFilename); 1046b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project needToRegisterRecording = true; 1047b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mMediaRecorderRecording = false; 1048b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1049b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project releaseMediaRecorder(); 1050b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project updateRecordingIndicator(false); 1051b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mRecordingTimeView.setVisibility(View.GONE); 1052b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenTimeoutLong(); 1053b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 10549a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project if (needToRegisterRecording && mStorageStatus == STORAGE_STATUS_OK) { 10559a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project registerVideo(); 10569a379bd668227d3dcea30312025f304fd248f6e3The Android Open Source Project } 1057b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1058b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCameraVideoFilename = null; 1059b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mCameraVideoFileDescriptor = null; 1060b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1061b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1062b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void setScreenTimeoutSystemDefault() { 1063b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mHandler.removeMessages(CLEAR_SCREEN_DELAY); 1064b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project clearScreenOnFlag(); 1065b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1066b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1067b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void setScreenTimeoutLong() { 1068b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mHandler.removeMessages(CLEAR_SCREEN_DELAY); 1069b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenOnFlag(); 1070b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mHandler.sendEmptyMessageDelayed(CLEAR_SCREEN_DELAY, SCREEN_DELAY); 1071b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1072b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1073b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void setScreenTimeoutInfinite() { 1074b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project mHandler.removeMessages(CLEAR_SCREEN_DELAY); 1075b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project setScreenOnFlag(); 1076b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1077b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1078b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void clearScreenOnFlag() { 1079b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Window w = getWindow(); 1080d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang final int flag = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; 1081d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang if ((w.getAttributes().flags & flag) != 0) { 1082d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang w.clearFlags(flag); 1083b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1084b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1085b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 1086b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project private void setScreenOnFlag() { 1087b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project Window w = getWindow(); 1088d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang final int flag = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; 1089d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang if ((w.getAttributes().flags & flag) == 0) { 1090d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang w.addFlags(flag); 1091b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1092b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1093b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 10949bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private void hideAlertAndStartPreview() { 10959bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang hideAlert(); 10969bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang initializeVideo(); 1097b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1098b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 10999bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private void hideAlertAndStartVideoRecording() { 11009bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang hideAlert(); 11019bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang startVideoRecording(); 1102b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1103b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 11049bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private void acquireVideoThumb() { 1105101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin Bitmap videoFrame = Util.createVideoThumbnail(mCurrentVideoFilename); 11069bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mThumbController.setData(mCurrentVideoUri, videoFrame); 1107de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 1108de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 11099bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private void showLastPictureButton() { 11109bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (!mIsVideoCaptureIntent) { 11119bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mLastPictureButton.setVisibility(View.VISIBLE); 1112de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 11139bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 1114de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 11159bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private void hideLastPictureButton() { 11169bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (!mIsVideoCaptureIntent) { 11179bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mLastPictureButton.setVisibility(View.INVISIBLE); 11189bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 1119de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 1120de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 11219bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private static ImageManager.DataLocation dataLocation() { 11229bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang return ImageManager.DataLocation.EXTERNAL; 1123de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project } 1124de365d87520c97d6b1636442e6b5c82a3e036f29The Android Open Source Project 11259bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private void updateLastVideo() { 1126101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin IImageList list = ImageManager.instance().allImages( 11279bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang this, 11289bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mContentResolver, 11299bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang dataLocation(), 11309bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang ImageManager.INCLUDE_VIDEOS, 11319bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang ImageManager.SORT_ASCENDING, 11329bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang ImageManager.CAMERA_IMAGE_BUCKET_ID); 11339bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang int count = list.getCount(); 11349bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (count > 0) { 1135d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang IImage image = list.getImageAt(count - 1); 11369bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang Uri uri = image.fullSizeImageUri(); 11379bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mThumbController.setData(uri, image.miniThumbBitmap()); 11389bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } else { 11399bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang mThumbController.setData(null, null); 11409bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 11419bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang list.deactivate(); 1142b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1143b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project 11449bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private static final String[] DATA_PATH_PROJECTION = new String[] { 11459bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang "_data" 11469bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang }; 11479bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang 11489bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang private String getDataPath(Uri uri) { 11499bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang Cursor c = null; 11509bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang try { 1151d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang c = mContentResolver.query(uri, DATA_PATH_PROJECTION, null, null, 1152d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang null); 11539bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang if (c != null && c.moveToFirst()) { 11549bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang return c.getString(0); 11559bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } else { 11569bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang return null; 11579bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } 11589bc8d1b47e5bab978cc9571ddfdedc8309a0b65dChih-Chung Chang } finally { 115923c51b794e95c201290e36737f379c4bb8eefeaeRay Chen if (c != null) { 116023c51b794e95c201290e36737f379c4bb8eefeaeRay Chen c.close(); 116123c51b794e95c201290e36737f379c4bb8eefeaeRay Chen } 1162b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1163b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project } 1164d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang 1165d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang private void updateRecordingTime() { 116623c51b794e95c201290e36737f379c4bb8eefeaeRay Chen if (!mMediaRecorderRecording) { 116723c51b794e95c201290e36737f379c4bb8eefeaeRay Chen return; 116823c51b794e95c201290e36737f379c4bb8eefeaeRay Chen } 1169d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang long now = SystemClock.uptimeMillis(); 1170d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang long delta = now - mRecordingStartTime; 1171d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang 1172d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // Starting a minute before reaching the max duration 1173d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // limit, we'll countdown the remaining time instead. 1174d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang boolean countdownRemainingTime = 1175d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang (delta >= MAX_RECORDING_DURATION_MS - 60000); 1176d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang 1177d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang if (countdownRemainingTime) { 1178d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang delta = Math.max(0, MAX_RECORDING_DURATION_MS - delta); 1179d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang } 1180d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang 1181d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang long seconds = (delta + 500) / 1000; // round to nearest 1182d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang long minutes = seconds / 60; 1183d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang long hours = minutes / 60; 1184d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang long remainderMinutes = minutes - (hours * 60); 1185d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang long remainderSeconds = seconds - (minutes * 60); 1186d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang 1187d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang String secondsString = Long.toString(remainderSeconds); 1188d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang if (secondsString.length() < 2) { 1189d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang secondsString = "0" + secondsString; 1190d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang } 1191d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang String minutesString = Long.toString(remainderMinutes); 1192d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang if (minutesString.length() < 2) { 1193d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang minutesString = "0" + minutesString; 1194d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang } 1195d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang String text = minutesString + ":" + secondsString; 1196d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang if (hours > 0) { 1197d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang String hoursString = Long.toString(hours); 1198d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang if (hoursString.length() < 2) { 1199d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang hoursString = "0" + hoursString; 1200d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang } 1201d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang text = hoursString + ":" + text; 1202d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang } 1203d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang mRecordingTimeView.setText(text); 1204d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang 1205d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang if (mRecordingTimeCountsDown != countdownRemainingTime) { 1206d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // Avoid setting the color on every update, do it only 1207d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // when it needs changing. 1208d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang 1209d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang mRecordingTimeCountsDown = countdownRemainingTime; 1210d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang 1211d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang int color = getResources().getColor( 1212d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang countdownRemainingTime 1213d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang ? R.color.recording_time_remaining_text 1214d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang : R.color.recording_time_elapsed_text); 1215d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang 1216d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang mRecordingTimeView.setTextColor(color); 1217d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang } 1218d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang 1219d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // Work around a limitation of the T-Mobile G1: The T-Mobile 1220d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // hardware blitter can't pixel-accurately scale and clip at the 1221d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // same time, and the SurfaceFlinger doesn't attempt to work around 1222d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // this limitation. In order to avoid visual corruption we must 1223d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // manually refresh the entire surface view when changing any 1224d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang // overlapping view's contents. 1225d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang mVideoPreview.invalidate(); 1226d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang mHandler.sendEmptyMessageDelayed(UPDATE_RECORD_TIME, 1000); 1227d8209aa01ae56ea27f551f621b419251bf80b265Chih-Chung Chang } 1228b64d345c9d51cabce43b5191532a0c185d2a70a5The Android Open Source Project} 1229