为什么我在测试MediaRecorder示例时会出现致命异常(FATAL EXCEPTION)?

5

我在使用 Android Studio 在我的真机上测试样例路径为 E:\Android_SDK\samples\android-22\media\MediaRecorder 的代码时,遇到了以下错误,请问是什么原因造成的?这个样例中是否存在一些 bug?

顺便提一下,我的安卓版本是 5.1。

09-28 16:09:31.683  17233-17233/com.example.android.mediarecorder E/Zygote﹕ v2
09-28 16:09:31.683  17233-17233/com.example.android.mediarecorder E/SELinux﹕ [DEBUG] get_category: variable seinfo: default sensitivity: NULL, cateogry: NULL
09-28 16:10:06.343  17233-17772/com.example.android.mediarecorder E/MediaRecorder﹕ start failed: -19
09-28 16:10:06.343  17233-17772/com.example.android.mediarecorder E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #1
    Process: com.example.android.mediarecorder, PID: 17233
    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.example.android.mediarecorder.MainActivity$MediaPrepareTask.doInBackground(MainActivity.java:208)
            at com.example.android.mediarecorder.MainActivity$MediaPrepareTask.doInBackground(MainActivity.java:200)
            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)

新增内容

另外,当我在AndroidManifest.xml中删除android:screenOrientation="landscape"后,它仍然可以正常工作,但我不知道为什么?


你是否在主线程上通过后台线程呈现进度条UI? - Ganesh Pandey
4个回答

3

MediaRecorder示例仅在横屏模式下工作,若要使其在竖屏模式下也能够工作,则需要按照以下确切顺序添加下列代码!

代码如下:

将以下内容添加到mCamera中以支持竖屏

mCamera.setDisplayOrientation(90);

要支持音频/视频编码器和输出格式,请添加以下内容:

            mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
            mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
            mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);

以下是您完整的方法prepareVideoRecorder
private boolean prepareVideoRecorder(){

        // BEGIN_INCLUDE (configure_preview)
        mCamera = CameraHelper.getDefaultCameraInstance();
        mCamera.setDisplayOrientation(90);
        // 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


        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.setVideoSource(MediaRecorder.VideoSource.CAMERA);
        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);

        mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
        mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
        mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);

        mMediaRecorder.setOrientationHint(90);

        // Step 3: Set a CamcorderProfile (requires API Level 8 or higher)

        mMediaRecorder.setOutputFile(CameraHelper.getOutputMediaFile(
                CameraHelper.MEDIA_TYPE_VIDEO).toString());
        //
        //mMediaRecorder.setPreviewDisplay(SufaceView);
        // Step 4: Set output file

        // END_INCLUDE (configure_media_recorder)

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

最后,您可以从清单中删除screenOrientation

android:screenOrientation="landscape"

以上代码将在两种 方向 中均可正常工作,但 相机 显示始终会是 90 度,因此您需要正确处理方向以进行更改。


谢谢!我测试了你的代码,它可以运行,但是我很奇怪为什么Android SDK会给出一个错误的示例代码。 - HelloCW

2

我之前使用上述的MediaRecorder样例时也遇到了问题,但我添加了"android:theme="@android:style/Theme.NoTitleBar.Fullscreen"后,样例项目在横屏模式下也可以正常工作。

<activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:screenOrientation="landscape"
            android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >>

谢谢!你的代码有效。但我很奇怪为什么Android SDK会给出一个错误的示例代码。 - HelloCW

1
理想情况下,您应该在Activity下包含android:screenOrientation="landscape",这告诉我您手头的示例项目已经过时。请确保运行最新版本的示例项目。要么通过以下方式打开项目:

文件 > 新建 > 导入示例 > 输入MediaRecorder

或者

git clone https://github.com/googlesamples/android-MediaRecorder.git

刚刚测试了Android 5.1(API级别22)的示例代码,在平板电脑和智能手机上都可以正常工作。请将android:theme="@style/AppTheme"保留在Application下,不要更改,因为示例代码并不提供它。模板样式定义在

res > values > template-styles.xml

中,并且为平板电脑和智能手机定义。

我测试了 https://github.com/googlesamples/android-MediaRecorder.git 的代码,但是我得到了相同的错误。顺便提一下,代码中 android:versionCode="1"。 - HelloCW

0

缺少权限

在MainActivity.java的onCreate中添加此调用

 if (!checkPermissionFromDevice())
        requestPermission();

并将这两个方法插入到MainActivity.java中

private boolean checkPermissionFromDevice()
{
    int write_external_storage_result = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
    int camera_result = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA);
    int record_audio_result = ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO);
    return write_external_storage_result == PackageManager.PERMISSION_GRANTED
            && camera_result == PackageManager.PERMISSION_GRANTED
            && record_audio_result == PackageManager.PERMISSION_GRANTED;
}

private void requestPermission()
{
    ActivityCompat.requestPermissions(
            this,
            new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO},
            REQUEST_PERMISSION_CODE);
}

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