I want to start recording a voice message with MediaRecorder
when I hold down a button. I am getting an IllegalStateException
when trying to start recording in a onLongClickListener
.
The error I am receiving as noted in the stacktrace is on Line 219: recorder.start()
Why is this happening?
btnSendVoice.setOnLongClickListener(new OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
isVoiceButtonHeld = true;
startRecording();
return false;
}
});
btnSendVoice.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent event) {
view.onTouchEvent(event);
if (event.getAction() == MotionEvent.ACTION_UP) {
if (isVoiceButtonHeld) {
isVoiceButtonHeld = false;
stopRecording();
}
}
return false;
}
});
private void startRecording() {
Toast.makeText(getActivity(), "Recording Message", Toast.LENGTH_SHORT).show();
filename = Environment.getExternalStorageDirectory().getAbsolutePath() + "/audiotest.3gp";
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setOutputFile(filename);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
try { recorder.prepare(); }
catch (IOException e) { Log.e("MediaRecorder", "prepare() failed"); }
recorder.start();
}
private void stopRecording() {
Toast.makeText(getActivity(), "Recording Finished", Toast.LENGTH_SHORT).show();
recorder.stop();
recorder.release();
recorder = null;
}
@Override
public void onPause() {
super.onPause();
// Free up resources from MediaRecorder when leaving Fragment
if (recorder != null) {
recorder.release();
recorder = null;
}
}
LogCat
07-15 16:24:32.256: E/MediaRecorder(4227): start failed: -38
07-15 16:24:32.256: D/AndroidRuntime(4227): Shutting down VM
07-15 16:24:32.256: W/dalvikvm(4227): threadid=1: thread exiting with uncaught exception (group=0x41551ba8)
07-15 16:24:32.406: E/AndroidRuntime(4227): FATAL EXCEPTION: main
07-15 16:24:32.406: E/AndroidRuntime(4227): Process: com.walintukai.lfdate, PID: 4227
07-15 16:24:32.406: E/AndroidRuntime(4227): java.lang.IllegalStateException
07-15 16:24:32.406: E/AndroidRuntime(4227): at android.media.MediaRecorder.start(Native Method)
07-15 16:24:32.406: E/AndroidRuntime(4227): at com.walintukai.lfdate.ChatFragment.startRecording(ChatFragment.java:219)
07-15 16:24:32.406: E/AndroidRuntime(4227): at com.walintukai.lfdate.ChatFragment.access$4(ChatFragment.java:206)
07-15 16:24:32.406: E/AndroidRuntime(4227): at com.walintukai.lfdate.ChatFragment$3.onLongClick(ChatFragment.java:132)
07-15 16:24:32.406: E/AndroidRuntime(4227): at android.view.View.performLongClick(View.java:4474)
07-15 16:24:32.406: E/AndroidRuntime(4227): at android.view.View$CheckForLongPress.run(View.java:18418)
07-15 16:24:32.406: E/AndroidRuntime(4227): at android.os.Handler.handleCallback(Handler.java:733)
07-15 16:24:32.406: E/AndroidRuntime(4227): at android.os.Handler.dispatchMessage(Handler.java:95)
07-15 16:24:32.406: E/AndroidRuntime(4227): at android.os.Looper.loop(Looper.java:136)
07-15 16:24:32.406: E/AndroidRuntime(4227): at android.app.ActivityThread.main(ActivityThread.java:5050)
07-15 16:24:32.406: E/AndroidRuntime(4227): at java.lang.reflect.Method.invokeNative(Native Method)
07-15 16:24:32.406: E/AndroidRuntime(4227): at java.lang.reflect.Method.invoke(Method.java:515)
07-15 16:24:32.406: E/AndroidRuntime(4227): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
07-15 16:24:32.406: E/AndroidRuntime(4227): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:605)
07-15 16:24:32.406: E/AndroidRuntime(4227): at dalvik.system.NativeStart.main(Native Method)
You forgot to add <uses-permission android:name="android.permission.RECORD_AUDIO" />
permission to record audio on your Manifest.xml
file.
Edit: Your onTouchListener
is interfering with onLongClickListener
and may be stopping your MediaRecorder
right after it is initialized and before it starts or even stopping it when the recorder is null. That gives origin to your Exception
.
Note that If you comment the line view.onTouchEvent(event);
, it starts recording, but it has an unpredictable behaviour from that moment on, according to the user action.
Be aware that the Event.ACTION_CANCEL
is possible to happen on your scenario and must be taken into account in order to have your recorder
stopped.
Make sure to check if your recorder
is not null before calling stop()
.