UPDATED:
Ok, after a few days of testing and debugging... I GOT IT TO WORK, but not the way I want.
The reason it crashed previously was because of "reorientation" of the camera during lockscreen, apparently, that crashes often.
Once I forced it to use landscape mode, it works. However, I don't want it to use landscape mode; I want it to work in portrait mode.
The code is taken directly from Android Studio's sample (Media -> MediaRecorder). The sample had the code working in landscape mode, and I can't figure how to get it to use portrait mode so I can avoid re-orientation and thus avoid the crashes?
There's nothing in the onPause, onResume code and the stacktrace pointed toward this method being called.
Easy Reproduce:
1) Use Android Studio to get the MediaRecord Sample app 2) In the manifest, change, android:screenOrientation="landscape"> to Portrait. 3) The App won't launch now.
I added mCamera.setDisplayOrientation(90), same issue.
Code:
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private boolean prepareVideoRecorder(){
// BEGIN_INCLUDE (configure_preview)
mCamera = CameraHelper.getDefaultCameraInstance();
// We need to make sure that our preview and recording video size are supported by the
// camera. Query camera to find all the sizes and choose the optimal size given the
// dimensions of our preview surface.
Camera.Parameters parameters = mCamera.getParameters();
List<Camera.Size> mSupportedPreviewSizes = parameters.getSupportedPreviewSizes();
Camera.Size optimalSize = CameraHelper.getOptimalPreviewSize(mSupportedPreviewSizes,
mPreview.getWidth(), mPreview.getHeight());
// Use the same size for recording profile.
CamcorderProfile profile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
profile.videoFrameWidth = optimalSize.width;
profile.videoFrameHeight = optimalSize.height;
// likewise for the camera object itself.
parameters.setPreviewSize(profile.videoFrameWidth, profile.videoFrameHeight);
mCamera.setParameters(parameters);
try {
// Requires API level 11+, For backward compatibility use {@link setPreviewDisplay}
// with {@link SurfaceView}
mCamera.setPreviewTexture(mPreview.getSurfaceTexture());
} catch (IOException e) {
Log.e(TAG, "Surface texture is unavailable or unsuitable" + e.getMessage());
return false;
}
// END_INCLUDE (configure_preview)
// BEGIN_INCLUDE (configure_media_recorder)
mMediaRecorder = new MediaRecorder();
// Step 1: Unlock and set camera to MediaRecorder
mCamera.unlock();
mMediaRecorder.setCamera(mCamera);
// Step 2: Set sources
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
// Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
mMediaRecorder.setProfile(profile);
// Step 4: Set output file
mMediaRecorder.setOutputFile(CameraHelper.getOutputMediaFile(
CameraHelper.MEDIA_TYPE_VIDEO).toString());
mMediaRecorder.setOrientationHint(90);
// END_INCLUDE (configure_media_recorder)
MediaScannerConnection.scanFile(this, new String[] { CameraHelper.getOutputMediaFile(
CameraHelper.MEDIA_TYPE_VIDEO).getPath() }, new String[] { "video/mp4" }, null);
// Step 5: Prepare configured MediaRecorder
try {
mMediaRecorder.prepare();
} catch (IllegalStateException e) {
Log.d(TAG, "IllegalStateException preparing MediaRecorder: " + e.getMessage());
releaseMediaRecorder();
return false;
} catch (IOException e) {
Log.d(TAG, "IOException preparing MediaRecorder: " + e.getMessage());
releaseMediaRecorder();
return false;
}
return true;
}
Logs:
06-27 02:18:08.244 25734-25752/com.watchdawg.watchdawg E/MediaRecorder﹕ start failed: -22
06-27 02:18:08.253 25734-25752/com.watchdawg.watchdawg E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #1
Process: com.watchdawg.watchdawg, PID: 25734
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:304)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.RuntimeException: start failed.
at android.media.MediaRecorder.start(Native Method)
at com.watchdawg.watchdawg.RecordActivity$MediaPrepareTask.doInBackground(RecordActivity.java:276)
at com.watchdawg.watchdawg.RecordActivity$MediaPrepareTask.doInBackground(RecordActivity.java:267)
at android.os.AsyncTask$2.call(AsyncTask.java:292)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
Whenever the application is removed from the recent task list, process will not be cleaned up completely, it is just that the UI will be cleaned up. So it is app responsibility to cleanup the resource held by your activity or app. Hence, you need to override onTaskRemoved() method in your service(Android service) component and perform cleanup(releasing mediaplayer instance etc).