MediaRecorder开始在无效状态下调用:4 || E / AudioRecording:prepare失败

问题描述

我在Record Audio应用程序中遇到了一个大问题,我在该网站上阅读了与该应用程序相关的所有帖子,并尝试了建议的每种解决方案,但没有解决我的问题。我的应用程序可以在所有来自AndroidQ 10.0 (SDK29)和以下版本的Android版本上正常运行,并且此问题仅出现在10.0 + 版本中,尤其是在 SDK30 中>。有谁知道如何解决它,或者对导致此错误的原因有任何想法吗?
以下是日志的打印内容 https://imgur.com/a/xSATHSp
清单: https://imgur.com/a/T6eEGmb
代码(第76行): https://imgur.com/a/lrmlB58
-------------------------------------------------- -------------------------------------------------- -------------------------------------------------- ------------------
我还在“ 可能出什么问题?”子主题下的 java.lang中尝试了其他论坛的其他解决方案。 IllegalStateException “: https://www.grokkingandroid.com/recording-audio-using-androids-mediarecorder-framework/

-------------------------------------------------- -------------------------------------------------- -------------------------------------------------- ------------------

我的日志例外:

E/AudioRecording: prepare() Failed
E/MediaRecorder: start called in an invalid state: 4
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.myfetus,PID: 17985
    java.lang.IllegalStateException
        at android.media.MediaRecorder.start(Native Method)
        at com.example.myfetus.MainActivity$1.onClick(MainActivity.java:81)
        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)


我的活动主要代码


public class MainActivity extends AppCompatActivity{
    private ImageButton recordbtn,stopbtn,playbtn,stopplay,pausebtn;
    private MediaRecorder mRecorder;
    private MediaPlayer mPlayer;
    private static final String LOG_TAG = "AudioRecording";
    private static String mFileName = null;
    public static final int REQUEST_AUdio_PERMISSION_CODE = 1;
    private int buttonState = 0;
    private EditText editsenha1;
    private TextView test1;
    private ImageView editimagem;
    private int i=0;
    Date createdTime = new Date();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        recordbtn = (ImageButton)findViewById(R.id.record);
        stopbtn = (ImageButton)findViewById(R.id.stopRecord);
        playbtn = (ImageButton)findViewById(R.id.play);
        stopplay = (ImageButton)findViewById(R.id.stopplay);
        pausebtn = (ImageButton)findViewById(R.id.pause);
        stopbtn.setEnabled(false);
        playbtn.setEnabled(false);
        stopplay.setEnabled(false);

        mFileName = (Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + "MyFetus" +createdTime + "Audio.m4a").replaceAll(" ","_").replaceAll(":","-");
        test1 = findViewById(R.id.texto2);
         editimagem = findViewById(R.id.imageView4);

        recordbtn.setonClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                    if (CheckPermissions()) {
                        stopbtn.setEnabled(true);
                        recordbtn.setEnabled(false);
                        playbtn.setEnabled(false);
                        stopplay.setEnabled(false);
                        pausebtn.setEnabled(false);
                        mRecorder = new MediaRecorder();
                        mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
                        mRecorder.setoutputFormat(MediaRecorder.OutputFormat.MPEG_4);
                        mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
                        mRecorder.setAudioEncodingBitRate(128000);
                        mRecorder.setAudioSamplingRate(44100);
                        mRecorder.setoutputFile(mFileName);
                        try {
                            mRecorder.prepare();

                        } catch (IOException e) {
                            Log.e(LOG_TAG,"prepare() Failed");
                        }
                        mRecorder.start();
                        Toast.makeText(getApplicationContext(),"Recording Started",Toast.LENGTH_LONG).show();
                        test1.setText("Gravando...");
                        test1.setTextColor(Color.parseColor("#0af263"));
                    } else {
                        RequestPermissions();
                    }
                    recordbtn.setVisibility(View.INVISIBLE);
                    stopbtn.setVisibility(View.VISIBLE);
                }


        });
        stopbtn.setonClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                stopbtn.setEnabled(false);
                recordbtn.setEnabled(true);
                playbtn.setEnabled(true);
                stopplay.setEnabled(true);
                pausebtn.setEnabled(true);
                mRecorder.stop();
                mRecorder.release();
                mRecorder = null;
                Toast.makeText(getApplicationContext(),"Recording Stopped",Toast.LENGTH_LONG).show();
                test1.setText("Aperte para gravar");
                test1.setTextColor(Color.parseColor("#FADCEE"));
                stopbtn.setVisibility(View.INVISIBLE);
                recordbtn.setVisibility(View.VISIBLE);
            }
        });
        playbtn.setonClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                stopbtn.setEnabled(false);
                recordbtn.setEnabled(true);
                playbtn.setEnabled(false);
                stopplay.setEnabled(true);
                pausebtn.setEnabled(true);
                mPlayer = new MediaPlayer();
                try {
                    mPlayer.setDataSource(mFileName);
                    mPlayer.prepare();
                    mPlayer.start();
                    Toast.makeText(getApplicationContext(),"Recording Started Playing",Toast.LENGTH_LONG).show();
                } catch (IOException e) {
                    Log.e(LOG_TAG,"prepare() Failed");
                }
            }
        });
        pausebtn.setonClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(mPlayer!=null){
                mPlayer.pause();
                stopbtn.setEnabled(true);
                recordbtn.setEnabled(true);
                playbtn.setEnabled(true);
                stopplay.setEnabled(true);
                pausebtn.setEnabled(false);
                Toast.makeText(getApplicationContext(),"Audio Paused",Toast.LENGTH_SHORT).show();}
            }
        });
        stopplay.setonClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mPlayer.release();
                mPlayer = null;
                stopbtn.setEnabled(false);
                recordbtn.setEnabled(true);
                playbtn.setEnabled(true);
                stopplay.setEnabled(false);
                pausebtn.setEnabled(true);
                Toast.makeText(getApplicationContext(),"Audio Stopped",Toast.LENGTH_SHORT).show();
            }
        });


    }

    @Override
    public void onRequestPermissionsResult(int requestCode,String[] permissions,int[] grantResults) {
        switch (requestCode) {
            case REQUEST_AUdio_PERMISSION_CODE:
                if (grantResults.length> 0) {
                    boolean permissionToRecord = grantResults[0] == PackageManager.PERMISSION_GRANTED;
                    boolean permissionToStore = grantResults[1] ==  PackageManager.PERMISSION_GRANTED;
                    if (permissionToRecord && permissionToStore) {
                        Toast.makeText(getApplicationContext(),"Permission Granted",Toast.LENGTH_LONG).show();
                    } else {
                        Toast.makeText(getApplicationContext(),"Permission Denied",Toast.LENGTH_LONG).show();
                    }
                }
                break;
        }
    }
    public boolean CheckPermissions() {
        int result = ContextCompat.checkSelfPermission(getApplicationContext(),WRITE_EXTERNAL_STORAGE);
        int result1 = ContextCompat.checkSelfPermission(getApplicationContext(),RECORD_AUdio);
        return result == PackageManager.PERMISSION_GRANTED && result1 == PackageManager.PERMISSION_GRANTED;
    }
    private void RequestPermissions() {
        ActivityCompat.requestPermissions(MainActivity.this,new String[]{RECORD_AUdio,WRITE_EXTERNAL_STORAGE},REQUEST_AUdio_PERMISSION_CODE);
    }
}

解决方法

Android 10或更高版本面临的问题是您cannot access files on the external SD card anymore。您必须先使用Storage Access Framework创建文件,然后将其用作存储的基础,或者仅使用应用程序专用存储。

或者-在这种情况下,恕我直言更好-您使用MediaStore content provider。有关how to add files to MediaStore的更多详细信息,请参见官方文档。

如果您使用MediaStore,则可以不再使用setOutputfile()。与setOutputFileDescriptor()内容提供商一起使用FileDescriptor代替MediaStore