Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
262 views
in Technique[技术] by (71.8m points)

java - App crash in Android Studio 4 emulator while testing recording and play

I've met with problems while testing a recording app on the emulator(Pixel 3a API 30)

Below is the Java code that I searched for in the tutorial on Youtube. In the video it can be tested normally. When it comes to me, it kept crashing when I hit on the stop recording button.

        //Request Runtime Permission
        if (!checkPermissionFromDevice())
            requestPermission();

        //Init view
        pl_btn = (Button)findViewById(R.id.play_btn);
        rcrd_btn = (Button)findViewById(R.id.record_button);
        stp_rcrd_btn = (Button)findViewById(R.id.stop_record_btn);
        ps_btn = (Button)findViewById(R.id.pause_btn);


        //From Android M, need request Run-time permission

            rcrd_btn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    if (checkPermissionFromDevice()) {

                        pathSave = Environment.getExternalStorageDirectory()
                                .getAbsolutePath() + "/"
                                + UUID.randomUUID().toString() + "audio_record.3gp";
                        setupMediaRecorder();
                        try {
                            mediaRecorder.prepare();
                            mediaRecorder.start();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }

                        pl_btn.setEnabled(false);
                        ps_btn.setEnabled(false);
                        rcrd_btn.setEnabled(false);
                        stp_rcrd_btn.setEnabled(true);

                        Toast.makeText(recording_and_play_test.this, "Recording...", Toast.LENGTH_SHORT).show();
                    } else {
                        requestPermission();
                    }
                }
            });

            stp_rcrd_btn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mediaRecorder.stop();
                    stp_rcrd_btn.setEnabled(false);
                    pl_btn.setEnabled(true);
                    rcrd_btn.setEnabled(true);
                    ps_btn.setEnabled(false);
                }
            });

            pl_btn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    ps_btn.setEnabled(true);
                    stp_rcrd_btn.setEnabled(false);
                    rcrd_btn.setEnabled(false);

                    mediaPlayer = new MediaPlayer();
                    try {
                        mediaPlayer.setDataSource(pathSave);
                        mediaPlayer.prepare();
                    }catch (IOException e){
                        e.printStackTrace();
                    }

                    mediaPlayer.start();
                    Toast.makeText(recording_and_play_test.this, "Playing...", Toast.LENGTH_SHORT).show();
                }
            });

            ps_btn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    stp_rcrd_btn.setEnabled(false);
                    rcrd_btn.setEnabled(true);
                    pl_btn.setEnabled(true);
                    ps_btn.setEnabled(false);

                    if (mediaPlayer != null){
                        mediaPlayer.stop();
                        mediaPlayer.release();
                        setupMediaRecorder();
                        
                    }
                }
            });

    }

    private void setupMediaRecorder() {
        mediaRecorder = new MediaRecorder();
        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        mediaRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);
        mediaRecorder.setOutputFile(pathSave);
    }

    private void requestPermission() {
        ActivityCompat.requestPermissions(this, new String[]{
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
                Manifest.permission.RECORD_AUDIO
        },REQUEST_PERMISSION_CODE);
    }

And here's what the activity looks like

Record and Play Activity

While I hit the stop recording button while executing the recording function, the app then just crashed and restarts again.

Here's what the build log says

E/MediaRecorder: stop called in an invalid state: 4
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.adrsingingscope, PID: 7309
    java.lang.IllegalStateException
        at android.media.MediaRecorder.stop(Native Method)
        at com.example.adrsingingscope.recording_and_play_test$2.onClick(recording_and_play_test.java:88)
        at android.view.View.performClick(View.java:7448)
        at android.view.View.performClickInternal(View.java:7425)
        at android.view.View.access$3600(View.java:810)
        at android.view.View$PerformClick.run(View.java:28305)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7656)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

This could be a problem with the path you created to save a file. These things can be easy to mess up. The media recorder has its own state and STATE 4 in which your app crashed in the state of recording. So it didn't stop and something happened in between that process so I assume it is related to saving your file to external storage.

You can find MEDIA_RECORDER_STATES here: https://android.googlesource.com/platform/frameworks/av/+/android-4.2.2_r1.2/include/media/mediarecorder.h#96

There are three things you can try.

  1. Change your save file path Try changing your path to a different directory. Sometimes you are trying to reach the directory you are not allowed to or it doesn't exist. More you can read in this answer: https://stackoverflow.com/a/33107120/14759470

  2. Check your AndroidManifest.xml for permissions Check if you wrote your permissions in AndroidManifest.xml as you should. You need WRITE_EXTERNAL_STORAGE and RECORD_AUDIO for this. In your code, it even says that from Android M (6.0) you need RUN_TIME permission. So just add them on top of your manifest file if you didn't.

  3. Make your code better Don't stop the recorder if it's already stopped. This will throw an exception. Don't release if already released, also an exception, and so on. So test your code for bugs, make breakpoints, and find your weak spots. It will be easier for you to find your errors. Also, check the log for more error messages since this one doesn't give us much.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...