MediaRecorder 停止时出错:在无效状态 4 下调用了停止函数。

6

我正在创建一个录音应用程序,当我尝试停止录音时,Java的Debug控制台显示:“MediaRecorder stop called in an invalid state : 4”。

这是我的一部分代码:

import java.io.File;
import java.io.IOException;
import com.androidexample.tabbar.R;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class Tab1 extends Activity implements OnClickListener{
private static final String AUDIO_RECORDER_FILE_EXT_3GP = ".3gp";
private static final String AUDIO_RECORDER_FILE_EXT_MP4 = ".mp4";
private static final String AUDIO_RECORDER_FOLDER = "AudioRecorder";

private MediaRecorder recorder = null;
private int currentFormat = 0;
private int output_formats[] = { MediaRecorder.OutputFormat.MPEG_4,
        MediaRecorder.OutputFormat.THREE_GPP };
private String file_exts[] = { AUDIO_RECORDER_FILE_EXT_MP4,
        AUDIO_RECORDER_FILE_EXT_3GP };

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.tab1);

    Button btnStart =(Button)findViewById(R.id.btnStart);
    btnStart.setOnClickListener(this);

    Button btnStop =(Button)findViewById(R.id.btnStop);
    btnStop.setOnClickListener(this);

    Button btnFormat =(Button)findViewById(R.id.btnFormat);
    btnFormat.setOnClickListener(this);


    enableButtons(false);
    setFormatButtonCaption();
}

private void setButtonHandlers() {

}

private void enableButton(int id, boolean isEnable) {
    ((Button) findViewById(id)).setEnabled(isEnable);
}

private void enableButtons(boolean isRecording) {
    enableButton(R.id.btnStart, !isRecording);
    enableButton(R.id.btnFormat, !isRecording);
    enableButton(R.id.btnStop, isRecording);
}

private void setFormatButtonCaption() {
    ((Button) findViewById(R.id.btnFormat))
            .setText(getString(R.string.audio_format) + " ("
                    + file_exts[currentFormat] + ")");
}

private String getFilename() {
    //String filepath = Environment.getExternalStorageDirectory().getPath();
    String filepath =Environment.getExternalStorageDirectory() + File.separator 
            + Environment.DIRECTORY_DCIM + File.separator + "FILE_NAME";
    File file = new File(filepath, AUDIO_RECORDER_FOLDER);


    if (!file.exists()) {
        file.mkdirs();
    }

    return (file.getAbsolutePath() + "/" + System.currentTimeMillis() + file_exts[currentFormat]);
}

private void startRecording() {
    recorder = new MediaRecorder();

    recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
    recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
    recorder.setOutputFile(getFilename());

    recorder.setOnErrorListener(errorListener);
    recorder.setOnInfoListener(infoListener);

    try {
        recorder.prepare();
        recorder.start();
    } catch (IllegalStateException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

private void stopRecording() {
    if (null != recorder){

            try {
                recorder.prepare();
            } catch (IllegalStateException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            recorder.stop();
            recorder.reset();
            recorder.release();

            recorder = null;

    }
}

private void displayFormatDialog() {
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    String formats[] = { "MPEG 4", "3GPP" };

    builder.setTitle(getString(R.string.choose_format_title))
            .setSingleChoiceItems(formats, currentFormat,
                    new DialogInterface.OnClickListener() {

                        @Override
                        public void onClick(DialogInterface dialog,
                                int which) {
                            currentFormat = which;
                            setFormatButtonCaption();

                            dialog.dismiss();
                        }
                    }).show();
}

private MediaRecorder.OnErrorListener errorListener = new MediaRecorder.OnErrorListener() {
    @Override
    public void onError(MediaRecorder mr, int what, int extra) {
        Toast.makeText(Tab1.this,
                "Error: " + what + ", " + extra, Toast.LENGTH_SHORT).show();
    }
};

private MediaRecorder.OnInfoListener infoListener = new MediaRecorder.OnInfoListener() {
    @Override
    public void onInfo(MediaRecorder mr, int what, int extra) {
        Toast.makeText(Tab1.this,
                "Warning: " + what + ", " + extra, Toast.LENGTH_SHORT)
                .show();
    }
};

@Override
public void onClick(View v) {
    // TODO Auto-generated method stub
switch(v.getId()){
case R.id.btnStart : 
    Toast.makeText(Tab1.this, "Start Recording",
            Toast.LENGTH_SHORT).show();

    enableButtons(true);
    startRecording();

    break;
case R.id.btnStop : 
    Toast.makeText(Tab1.this, "Stop Recording",
            Toast.LENGTH_SHORT).show();
    enableButtons(false);
    stopRecording();

    break;

case R.id.btnFormat : 
    displayFormatDialog();

    break;



}

}

}

而这是我的Log Cat信息:
07-30 15:11:21.972: E/MediaRecorder(836): stop called in an invalid state: 4
07-30 15:11:21.972: D/AndroidRuntime(836): Shutting down VM
07-30 15:11:21.972: W/dalvikvm(836): threadid=1: thread exiting with uncaught exception (group=0x4001d800)
07-30 15:11:21.982: E/AndroidRuntime(836): FATAL EXCEPTION: main
07-30 15:11:21.982: E/AndroidRuntime(836): java.lang.IllegalStateException
07-30 15:11:21.982: E/AndroidRuntime(836):  at android.media.MediaRecorder.stop(Native Method)

你好,Amin。你能帮我解决关于MediaRecorder的问题吗?我遇到了你曾经遇到过的同样的异常。这是链接。如果你能帮忙,请告诉我。https://stackoverflow.com/questions/49296213/android-mediarecorder-exception-when-stopped - jobin
1个回答

3
private void stopRecording() {
    if (null != recorder){
        try {
            recorder.prepare();  <-- Here's the problem

当您停止录制器MediaRecorder时,不应调用prepare方法。 prepare方法是在启动录制器之前调用的。请参考MediaRecorder文档中的状态图

谢谢您的回复。首先,我没有使用prepare()方法。即使没有这个方法,我仍然遇到了同样的问题:“在无效状态4下调用停止”。:( - AminH86
1
在这种情况下,您的录制可能一开始就没有正确启动。请查看日志中的其他异常或错误消息。 - Michael
2
谢谢你,Michael。问题出在SD卡的写入权限上。我只需要在清单文件中添加权限规则,问题就解决了。非常感谢你! - AminH86

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