代码之家  ›  专栏  ›  技术社区  ›  Jakub Gabčo

启动媒体录制器时发生IllegalStateException

  •  0
  • Jakub Gabčo  · 技术社区  · 7 年前

    我在应用程序中获取振幅时遇到问题。

    我的 开始 方法

    public void start() {
        if (mRecorder == null) {
            try {
                mRecorder = new MediaRecorder();
    
                mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
                mRecorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_WB);
                mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_WB);
                mRecorder.setOutputFile("/dev/null");
                try {
                    mRecorder.prepare();
                    mRecorder.start();
                } catch (IOException e) {
                    e.printStackTrace();
                        mRecorder = null;
                } catch(IllegalStateException e ){
                    e.printStackTrace();
                    mRecorder = null;
                }
    
            } catch (RuntimeException e) {
                e.printStackTrace();
            }
        }
    }
    

    还有我的 停止 方法:

    public void stop() {
        if (mRecorder != null) {
            try {
                mRecorder.stop();
            } catch (RuntimeException stopException) {
                //handle cleanup here
            } finally {
                mRecorder.release();
            }
            mRecorder = null;
        }
    }
    

    它抛出 非法状态例外 在…上

    mRecorder.start();
    

    我尝试了不同的输出格式和音频编码器,但都不起作用。:/也在不同的手机上试用过。

    这是我的stacktrace。

    W/MediaRecorder: mediarecorder went away with unhandled events
    E/MediaRecorder: start failed: -38
    W/System.err: java.lang.IllegalStateException
    W/System.err:     at android.media.MediaRecorder.start(Native Method)
    W/System.err:     at com.oscarsenior.oscar.util.sensorHelpers.SoundMeter.start(SoundMeter.java:33)
    W/System.err:     at com.oscarsenior.oscar.util.service.SensorService.updateAmplitude(SensorService.java:616)
    W/System.err:     at com.oscarsenior.oscar.util.service.SensorService$6.onSensorChanged(SensorService.java:606)
    

    我每15分钟运行一次,持续3秒,以测量最大振幅。

    2 回复  |  直到 7 年前
        1
  •  0
  •   Saurabh Vadhva    7 年前

    首先允许权限

    <uses-permission 
    android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    

    然后start()方法

    MediaRecorder mRecorder;
    File file;
    
    public void start() {
        if (mRecorder == null) {
            try {
                mRecorder = new MediaRecorder();
    
                file = new File(Environment.getExternalStorageDirectory() + "/Demo");
                if (!file.exists())
                    file.mkdir();
                mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    
                mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
                mRecorder.setOutputFile(file.getAbsoluteFile() + "/demoAudio.mp3");
                mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
    
                //mRecorder.setOutputFile();
                try {
                    mRecorder.prepare();
                    mRecorder.start();
                } catch (IOException e) {
                    e.printStackTrace();
                    mRecorder = null;
                } catch (IllegalStateException e) {
                    e.printStackTrace();
                    mRecorder = null;
                }
    
            } catch (RuntimeException e) {
                e.printStackTrace();
            }
        }
    }
    

    然后停止()方法

    public void stop() {
        if (mRecorder != null) {
            try {
                mRecorder.stop();
            } catch (RuntimeException stopException) {
                //handle cleanup here
            } finally {
                mRecorder.release();
            }
            mRecorder = null;
        }
    }
    

    并在应用程序处于后台时使用此方法停止录制

    @Override
    protected void onStop() {
        super.onStop();
        stop();
    }
    
        2
  •  0
  •   Jakub Gabčo    7 年前

    我终于找到了解决问题的办法。

    问题在于我的服务。我同时使用了两次MediaRecorder MediaRecorder。音频源 .

    解决方法是使用相同的 mRecorder 对于这两种情况。

    所以我创造了 单身汉 从我的 声音计

    protected SoundMeter(){
    
    }
    
    public static SoundMeter getInstance(){
        if(instance == null){
            instance = new SoundMeter();
        }
        if(!instance.isRecording || instance.mRecorder == null){
            instance.start();
        }
        return instance;
    }
    

    所以我得到了 声音计 如果实例 mRecorder 未初始化,我将使用相同的 声音计。开始() 方法。

    我补充道 mRecorder。重置() 停止() 方法,so发布 mRecorder 将清除其状态。也许我可以释放 媒体记录器 结束后,并不是每次我都会停下来听一阵子,而是在我不需要的时候在后台释放一些内存。

    if (mRecorder != null) {
        try {
            mRecorder.stop();
        } catch (RuntimeException stopException) {
            //handle cleanup here
        } finally {
            mRecorder.reset();
            mRecorder.release();
        }
        mRecorder = null;
        isRecording = false;
    }