MessageQueue回调中的异常:录音机的handleReceiveCallback

时间:2018-10-15 10:28:39

标签: java android

我有一个应用程序,可让您按住一个按钮来通过麦克风录制消息,放开该按钮将停止录制并播放它。但是,按住按钮,说出一条消息然后释放它会产生以下巨大错误:

  

10-15 21:19:42.539 20088-20088 / com.example.lbwde.senioraid E / MediaRecorder:在无效状态下停止调用:4   10-15 21:19:42.539 20088-20088 / com.example.lbwde.senioraid E / InputEventReceiver:调度输入事件的异常。   10-15 21:19:42.539 20088-20088 / com.example.lbwde.senioraid E / MessageQueue-JNI:MessageQueue回调中的异常:handleReceiveCallback   10-15 21:19:42.541 20088-20088 / com.example.lbwde.senioraid E / MessageQueue-JNI:java.lang.IllegalStateException           在android.media.MediaRecorder.stop(本机方法)           在com.example.lbwde.senioraid.ChatActivity.stopRecording(ChatActivity.java:539)

代码如下:

private FloatingActionButton = voiceMsg;
private MediaRecorder audioRecord;
private MediaPlayer mediaPlayer;
private String audioOutput;

onCreate中:

    voiceMsg = findViewById(R.id.voiceMsg);
    audioOutput = Environment.getExternalStorageDirectory()+"/audiomsg.3gpp";

    voiceMsg.setOnTouchListener(new View.OnTouchListener() {
        @SuppressLint("ClickableViewAccessibility")
        @Override
        public boolean onTouch(View view, MotionEvent event) {
            if(event.getAction() == MotionEvent.ACTION_DOWN) {

                try {

                    startRecording();
                }
                catch (Exception e) {
                    e.printStackTrace();
                }
            } else if (event.getAction() == MotionEvent.ACTION_UP) {
                stopRecording();
                try {
                    playRecording();
                }
                catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return true;
        }

    });

以及录制/播放方法:

private void startRecording() throws Exception {
    ditchRecorder();
    File output = new File (audioOutput);
    if (output.exists()) output.delete();

    audioRecord = new MediaRecorder();
    audioRecord.setAudioSource(MediaRecorder.AudioSource.MIC);
    audioRecord.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
    audioRecord.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_WB);
    audioRecord.setOutputFile(audioOutput);
    audioRecord.prepare();
    audioRecord.start();
}

private void playRecording() throws Exception {
    ditchMediaPlayer();
    mediaPlayer = new MediaPlayer();
    mediaPlayer.setDataSource(audioOutput);
    mediaPlayer.prepare();
    mediaPlayer.start();
}

private void ditchMediaPlayer() {
    if (mediaPlayer != null) {
        try {
            mediaPlayer.release();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}

private void stopPlayback() {
    if (mediaPlayer != null) {
        mediaPlayer.stop();
    }
}
private void stopRecording() {
    if (audioRecord != null) {
        audioRecord.stop();
    }
}

private void ditchRecorder() {
    if (audioRecord != null) {
        audioRecord.release();
    }
}

过去我有类似的错误,可以通过在代码执行中增加短暂的延迟来解决,但是这次却导致了更多的错误。

1 个答案:

答案 0 :(得分:0)

我认为您可能错误地管理了MediaRecorderMediaPlayer的状态。您甚至得到java.lang.IllegalStateException at android.media.MediaRecorder.stop清楚地表明您的状态有问题的信息。查看Android官方文档中MediaRecorder的状态图。

MediaRecorder State Diagram

我看到您正在使用MediaRecorder方法发布recorder.release(),然后再进行录制,并使用MediaPlayer做同样的事情。我认为这是不正确的。根据文档,MediaRecorder对象在发布后不能重复使用。尝试根据文档重新组织您的状态管理,以使其正确。