java.lang.IllegalStateException at android.media.MediaRecorder.start when calling MediaRecorder.start in onLongClickListener

The Nomad picture The Nomad · Jul 16, 2014 · Viewed 10.1k times · Source

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)

Answer

joao2fast4u picture joao2fast4u · Jul 16, 2014

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().