我正在尝试开发一个 activity,用户可以在其中录制音频并将其保存在内部存储器中

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

我正在尝试开发一个 activity,我可以在其中录制我的音频,直到我在移动按钮被释放时触摸我的按钮,文件应该保存在存储器中。该文件已创建并保存在文件夹中,但是当我正常单击按钮时,会发生错误。我已尽力做到最好,但每次都会出错。收到一条错误消息

java.lang.RuntimeException: 停止失败。 在 android.media.MediaRecorder.stop(本机方法)

请帮助我完成我的项目。

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

发生这种情况是因为您试图在 MediaRecorder 准备好之前停止它,一个快速的解决方案可能是这样的:

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

勾选 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.