安卓MediaRecorder崩溃问题

5

更新:

好的,经过几天的测试和调试……我成功了,但不是我想要的方式。

之前崩溃的原因是由于在锁屏期间相机的“重新定位”,这很容易导致崩溃。

一旦我强制它使用横屏模式,它就可以工作了。然而,我不想让它使用横屏模式;我想让它在竖屏模式下工作。

代码直接从Android Studio的示例(Media->MediaRecorder)中取得。示例中的代码在横屏模式下工作,我无法弄清楚如何使其在竖屏模式下工作,以避免重新定位和崩溃?

onPause、onResume中没有任何代码,堆栈跟踪也没有指向该方法被调用。

简单重现:

1)使用Android Studio获取MediaRecord示例应用程序
2)在清单中将android:screenOrientation="landscape">更改为Portrait。
3)应用程序现在无法启动。

我添加了mCamera.setDisplayOrientation(90),但问题仍然存在。

代码:

@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;
}

日志:

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)

亲爱的,我在Android Studio中执行https://github.com/googlesamples/android-MediaRecorder这个演示时没有收到任何错误。你遇到错误时采取了哪些步骤? - Rajan Bhavsar
请回复,如果您想解决它? - Rajan Bhavsar
你想做什么?你想让你的应用在后台运行吗? - siva
所以我的问题是...通过启动器启动默认活动与通过 context.startActivity(intent) 调用它是否有区别? - Ying Li
1
你也应该发布你的onPause和onResume代码 - nandeesh
显示剩余3条评论
2个回答

4
无论何时应用程序从最近的任务列表中删除,进程都不会完全清除,只是UI将被清除。因此,应用程序有责任清理由您的活动或应用程序持有的资源。因此,您需要在您的服务(Android服务组件)中覆盖onTaskRemoved()方法并执行清理(释放mediaplayer实例等)。

他实际上并没有在一个服务中运行它。 - Zharf
我同意,现在我建议他使用一个服务,并在用户从最近应用中滑动该应用时执行清理。 - siva
这是一个活动,而不是服务...我检查了我的清理工作,因为我解除了锁屏并以不同的方式滥用了我的应用程序启动和关闭方式...从未崩溃。只是无法通过锁屏接收器的startActivity(intent)启动。 - Ying Li
我的onPause和onResume代码为空。我分离了问题,是在锁屏期间屏幕重新定位导致应用崩溃。显然,这无法修复,但我可以通过匹配手机的默认方向来防止应用程序重新定位自身。这并不理想,所以我宁愿找出如何停止Activity重新定位(我的默认值为纵向,因此我需要应用程序接受纵向模式)。 - Ying Li

-1

尝试这种方式:

 mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
    mMediaRecorder.setVideoFrameRate(24);
    mMediaRecorder.setVideoSize(720,480);
    mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
    mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
    mPreview.setRotation(90);

试试这个:mMediaRecorder.setProfile(profile);

希望它能正常工作!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接