My android app crashes, touch button fails to work properly

Greg :

I am building an app that records and plays audio. I use a touch button to record. Audio is recorded successfully on prolonged touch, but if i tap the button without holding my finger on it for more than one second, my app crashes.

    mRecordBtn.setOnTouchListener(new View.OnTouchListener(){
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
            if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
                startRecording();
                mRecordLabel.setText("Recording...");
            }
            else if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
                stopRecording();
                mRecordLabel.setText("Recording stopped");
            }
            return false;
        }
    });

    private void startRecording() {
        recorder = new MediaRecorder();
        recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
        recorder.setOutputFile(fileName);
        recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);

        try {
            recorder.prepare();
        } catch (IOException e) {
            Log.e(LOG_TAG, "prepare() failed");
        }
        recorder.start();
    }

    private void stopRecording() {
        recorder.stop();
        recorder.release();
        recorder = null;
    }

Logcat when prolonged touching (no error):

    D/ViewRootImpl@406d73a[MainActivity]: ViewPostIme pointer 0
    I/MediaRecorderJNI: setup
    I/MediaRecorderJNI: setAudioSource(1)
    I/MediaRecorderJNI: setAudioEncoder(3)
    I/MediaRecorderJNI: setOutputFile
    I/MediaRecorderJNI: prepare
    I/MediaRecorderJNI: start
    D/ViewRootImpl@406d73a[MainActivity]: ViewPostIme pointer 1
    I/MediaRecorderJNI: stop
    I/MediaRecorderJNI: release
    W/MediaRecorder: mediarecorder went away with unhandled events

Logcat when tapping:

    D/ViewRootImpl@d597feb[MainActivity]: ViewPostIme pointer 0
    I/MediaRecorderJNI: setup
    I/MediaRecorderJNI: setAudioSource(1)
    I/MediaRecorderJNI: setAudioEncoder(3)
    I/MediaRecorderJNI: setOutputFile
    I/MediaRecorderJNI: prepare
    I/MediaRecorderJNI: start
    D/ViewRootImpl@d597feb[MainActivity]: ViewPostIme pointer 1
    I/MediaRecorderJNI: stop
    E/MediaRecorder: stop failed: -1007
    E/InputEventReceiver: Exception dispatching input event.
    E/MessageQueue-JNI: Exception in MessageQueue callback: handleReceiveCallback
    E/MessageQueue-JNI: java.lang.RuntimeException: stop failed.
        at android.media.MediaRecorder._stop(Native Method)
        at android.media.MediaRecorder.stop(MediaRecorder.java:1340)
        at tk.gandriks.gaaudiotransform.MainActivity.stopRecording(MainActivity.java:162)
        at tk.gandriks.gaaudiotransform.MainActivity.access$200(MainActivity.java:34)
        at tk.gandriks.gaaudiotransform.MainActivity$1.onTouch(MainActivity.java:78)
        at android.view.View.dispatchTouchEvent(View.java:12536)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3159)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2844)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3159)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2844)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3159)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2844)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3159)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2844)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3159)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2844)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3159)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2844)
        at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:601)
        at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1871)
        at android.app.Activity.dispatchTouchEvent(Activity.java:3384)
        at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:68)
        at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:563)
        at android.view.View.dispatchPointerEvent(View.java:12788)
        at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:5670)
        at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:5465)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4958)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:5011)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4977)
        at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:5114)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4985)
        at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:5171)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4958)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:5011)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4977)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4985)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4958)
        at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:7736)
        at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:7676)
        at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:7637)
        at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:7847)
        at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:197)
        at android.os.MessageQueue.nativePollOnce(Native Method)
        at android.os.MessageQueue.next(MessageQueue.java:325)
        at android.os.Looper.loop(Looper.java:142)
        at android.app.ActivityThread.main(ActivityThread.java:6944)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
    D/AndroidRuntime: Shutting down VM
    E/AndroidRuntime: FATAL EXCEPTION: main
    Process: tk.gandriks.gaaudiotransform, PID: 20802
    java.lang.RuntimeException: stop failed.
        at android.media.MediaRecorder._stop(Native Method)
        at android.media.MediaRecorder.stop(MediaRecorder.java:1340)
        at tk.gandriks.gaaudiotransform.MainActivity.stopRecording(MainActivity.java:162)
        at tk.gandriks.gaaudiotransform.MainActivity.access$200(MainActivity.java:34)
        at tk.gandriks.gaaudiotransform.MainActivity$1.onTouch(MainActivity.java:78)
        at android.view.View.dispatchTouchEvent(View.java:12536)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3159)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2844)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3159)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2844)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3159)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2844)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3159)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2844)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3159)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2844)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3159)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2844)
        at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:601)
        at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1871)
        at android.app.Activity.dispatchTouchEvent(Activity.java:3384)
        at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:68)
        at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:563)
        at android.view.View.dispatchPointerEvent(View.java:12788)
        at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:5670)
        at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:5465)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4958)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:5011)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4977)
        at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:5114)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4985)
        at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:5171)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4958)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:5011)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4977)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4985)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4958)
        at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:7736)
        at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:7676)
        at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:7637)
        at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:7847)
        at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:197)
        at android.os.MessageQueue.nativePollOnce(Native Method)
        at android.os.MessageQueue.next(MessageQueue.java:325)
        at android.os.Looper.loop(Looper.java:142)
        at android.app.ActivityThread.main(ActivityThread.java:6944)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
    I/zygote64: Do partial code cache collection, code=29KB, data=20KB
    After code cache collection, code=28KB, data=20KB
    Increasing code cache capacity to 128KB
    I/MediaRecorderJNI: finalize
    release
    Application terminated.

I can tell there is something wrong when stopping the recording process, but i can't seem to fix it on my own...

Kou Peto :

The prepare needs some time to be executed, so when tapping you are trying to stop the recorder but you are not sure that it has already started, you can have a variable isStarted to check or surround the stop with a try catch.

Solution 1

 private void startRecording() {
    recorder = new MediaRecorder();
    recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
    recorder.setOutputFile(fileName);
    recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);

    try {
        recorder.prepare();
    } catch (IOException e) {
        Log.e(LOG_TAG, "prepare() failed");
    }

    recorder.start();
    isStarted = true;
}

private void stopRecording() {
  if(isStarted) {
    recorder.stop();
    recorder.release();
    recorder = null;
    isStarted = false;
  }
}

Solution 2

private void stopRecording() {
  try {
      recorder.stop();
      recorder.release();
      recorder = null;
  } catch(Exception e) {}
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=156712&siteId=1