java - MessageQueue 回调中的异常:用于录音机的 handleReceiveCallback
问题描述
我有一个应用程序,可让您按住一个按钮通过麦克风录制消息,并在释放时停止录制并播放。但是,按住按钮,说出一条消息然后释放它会产生这个巨大的错误:
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.seniorid 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.senioaid E/MessageQueue-JNI:在 com.example.lbwde.senioraid.ChatActivity.stopRecording(ChatActivity.java:539) 的 android.media.MediaRecorder.stop(Native Method) 处的 java.lang.IllegalStateException
这是代码:
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();
}
}
过去我也遇到过类似的错误,通过增加代码执行的短暂延迟来解决,但这次却导致了更多错误。
解决方案
我认为您可能正在管理MediaRecorder
orMediaPlayer
不正确的状态。您甚至会java.lang.IllegalStateException at android.media.MediaRecorder.stop
清楚地表明您的状态有问题。看看MediaRecorder
Android 官方文档中的状态图。
我看到您在录制之前MediaRecorder
使用方法发布并使用. 我认为这是不正确的。根据文档,对象在发布后不能重复使用。尝试根据文档重新组织您的状态管理以使其正确。recorder.release()
MediaPlayer
MediaRecorder
推荐阅读
- javascript - 如何在 TypeScript 中将箭头函数返回值分配给字符串 []
- node.js - 在本地其他项目中使用修改后的 Angular cdk 模块
- javascript - 角度http请求不起作用,但邮递员工作
- swift - Audiokit 的 AKAudioFile 基本目录输入问题
- sql-server-2012 - 使用不同的运算符重复
- c# - 如何在使用 QnA 制造商服务的聊天机器人应用程序中接收用户输入
- android - 在两个堆栈之间传递参数 - React Native
- python - 将权重从 TensorFlow 检查点加载到 Keras 模型
- typescript - 如何声明只公开一个功能的 UMD 模块?
- perl - Perl 语法 <$VARIABLE> 是什么意思?