Search code examples
javaandroidvoice-recording

I am trying to develop an activity in which user can record and save there audio in the internal storage


I am trying to develop an activity in which I can record my audio until I touch my button at the movement button is been released the file should be saved in the storage. The file gets created and been saved inside the folder but when I click the button as a normal, error occurs. I have tried my level best to do but every time I get an error. getting an error that says

java.lang.RuntimeException: stop failed. at android.media.MediaRecorder.stop(Native Method)

Please help me so that I can complete my project.

     private void audiorecordermethod(){
   if(checkPermission()){
       capturebutton.setOnTouchListener(new View.OnTouchListener() {
           @Override
           public boolean onTouch(View v, MotionEvent event) {
               if(event.getAction() == MotionEvent.ACTION_DOWN){
                   validateMicAvailability();
                   AudioSavePathInDevice =
                           Environment.getExternalStorageDirectory().getAbsolutePath() + "/Alpha/Voice/Send/" ;
                   File audiodir = new File(AudioSavePathInDevice);
                   if (!audiodir.exists()){
                       audiodir.mkdirs();
                   }
                   String filepath = audiodir + "/"+ CreateRandomAudioFileName(5) + ".3gp";
                   MediaRecorderReady(filepath);

                   try {
                       mediaRecorder.prepare();
                       mediaRecorder.start();
                   } catch (IllegalStateException e) {
                       // TODO Auto-generated catch block
                       e.printStackTrace();
                   } catch (IOException e) {
                       // TODO Auto-generated catch block
                       e.printStackTrace();
                   }

                   return true;
               }else if(event.getAction() == MotionEvent.ACTION_UP){

                      mediaRecorder.stop();
                      mediaRecorder.release();

                   return true;
               }
               return false;
           }
       });
   }else{
       requestPermission();
   }
}

public void MediaRecorderReady(String filepath){
    mediaRecorder=new MediaRecorder();

        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        mediaRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);
        mediaRecorder.setOutputFile(filepath);
        mediaRecorder.setAudioChannels(1);
        mediaRecorder.setAudioSamplingRate(8000);
        mediaRecorder.setAudioEncodingBitRate(44100);

}

public String CreateRandomAudioFileName(int string){
    StringBuilder stringBuilder = new StringBuilder( string );
    int i = 0 ;
    while(i < string ) {
        stringBuilder.append(RandomAudioFileName.
                charAt(random.nextInt(RandomAudioFileName.length())));

        i++ ;
    }
    return stringBuilder.toString();
}

private void requestPermission() {
    ActivityCompat.requestPermissions(personalChat.this, new
            String[]{WRITE_EXTERNAL_STORAGE, RECORD_AUDIO}, RequestPermissionCode);
}

@Override
public void onRequestPermissionsResult(int requestCode,
                                       String permissions[], int[] grantResults) {
    switch (requestCode) {
        case RequestPermissionCode:
            if (grantResults.length> 0) {
                boolean StoragePermission = grantResults[0] ==
                        PackageManager.PERMISSION_GRANTED;
                boolean RecordPermission = grantResults[1] ==
                        PackageManager.PERMISSION_GRANTED;

                if (StoragePermission && RecordPermission) {
                    Toast.makeText(personalChat.this, "Permission Granted",
                            Toast.LENGTH_LONG).show();
                } else {
                    Toast.makeText(personalChat.this,"Permission Denied",Toast.LENGTH_LONG).show();
                }
            }
            break;
    }
}

public boolean checkPermission() {
    int result = ContextCompat.checkSelfPermission(getApplicationContext(),
            WRITE_EXTERNAL_STORAGE);
    int result1 = ContextCompat.checkSelfPermission(getApplicationContext(),
            RECORD_AUDIO);
    return result == PackageManager.PERMISSION_GRANTED &&
            result1 == PackageManager.PERMISSION_GRANTED;
}

Logcat

 10-24 15:50:51.762 9687-9687/com.nanb.alpha E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.nanb.alpha, PID: 9687
java.lang.RuntimeException: stop failed.
    at android.media.MediaRecorder.stop(Native Method)
    at com.nanb.alpha.personalChat$7.onTouch(personalChat.java:312)
    at android.view.View.dispatchTouchEvent(View.java:8476)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2408)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2107)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2408)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2107)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2408)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2107)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2408)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2107)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2408)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2107)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2408)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2107)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2408)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2107)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2408)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2107)
    at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2402)
    at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1752)
    at android.app.Activity.dispatchTouchEvent(Activity.java:2785)
    at androidx.appcompat.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:69)
    at androidx.appcompat.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:69)
    at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2363)
    at android.view.View.dispatchPointerEvent(View.java:8677)
    at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4144)
    at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4010)
    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3565)
    at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3618)
    at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3584)
    at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3701)
    at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3592)
    at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3758)
    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3565)
    at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3618)
    at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3584)
    at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3592)
    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3565)
    at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5828)
    at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5802)
    at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5773)
    at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:5918)
    at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
    at android.os.MessageQueue.nativePollOnce(Native Method)
    at android.os.MessageQueue.next(MessageQueue.java:143)
    at android.os.Looper.loop(Looper.java:122)
    at android.app.ActivityThread.main(ActivityThread.java:5268)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:902)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:697)

Solution

  • This happens because you try to stop the MediaRecorder before it is prepared, a quick solution could be this:

    try{
        mediaRecorder.stop();
        mediaRecorder.release();
    }catch (Exception e){
    }
    

    Check the Documentation:

    Note that a RuntimeException is intentionally thrown to the application, if no valid audio/video data has been received when stop() is called. This happens if stop() is called immediately after start(). The failure lets the application take action accordingly to clean up the output file (delete the output file, for instance), since the output file is not properly constructed when this happens.