简体   繁体   English

Android:录制音频应用程序崩溃

[英]Android : Record audio app crash

Everybody,大家,

I'm trying to make a simple audio recording.我正在尝试进行简单的录音。

The audio is record perfectly when record button is clicked.单击录制按钮时,音频录制完美。

I try to record another audio and play it back.我尝试录制另一个音频并播放。 It crash when I try to play the 2nd audio.当我尝试播放第二个音频时它崩溃了。

Can you please help me on fixing this app so that I can record audio multiple time without crashing the app.你能帮我修复这个应用程序,这样我就可以多次录制音频而不会导致应用程序崩溃。

Here's the code.这是代码。

  stop.setEnabled(false);
  play.setEnabled(false);
  outputFile = Environment.getExternalStorageDirectory().getAbsolutePath() + "/recording.3gp";;

  myAudioRecorder=new MediaRecorder();
  myAudioRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
  myAudioRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
  myAudioRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);
  myAudioRecorder.setOutputFile(outputFile);

  record.setOnClickListener(new View.OnClickListener() {
     @Override
     public void onClick(View v) {
        try {
           myAudioRecorder.prepare();
           myAudioRecorder.start();
        }


        catch (IllegalStateException e) {
           // TODO Auto-generated catch block
           e.printStackTrace();
        }

        catch (IOException e) {
           // TODO Auto-generated catch block
           e.printStackTrace();
        }

        record.setEnabled(false);
        stop.setEnabled(true);

        Toast.makeText(getApplicationContext(), "Recording started", Toast.LENGTH_LONG).show();
     }
  });

  stop.setOnClickListener(new View.OnClickListener() {
     @Override
     public void onClick(View v) {
        myAudioRecorder.stop();
        myAudioRecorder.reset();

        record.setEnabled(true);
        stop.setEnabled(false);
        play.setEnabled(true);

        Toast.makeText(getApplicationContext(), "Audio recorded successfully",Toast.LENGTH_LONG).show();
     }
  });

 play.setOnClickListener(new View.OnClickListener() {
     @Override
     public void onClick(View v) throws IllegalArgumentException,SecurityException,IllegalStateException {
        MediaPlayer m = new MediaPlayer();

        try {
           m.setDataSource(outputFile);
        }

        catch (IOException e) {
           e.printStackTrace();
        }

        try {
           m.prepare();
        }

        catch (IOException e) {
           e.printStackTrace();
        }

        m.start();
        Toast.makeText(getApplicationContext(), "Playing audio", Toast.LENGTH_LONG).show();
     }
  });

Thanks!谢谢!

You don't seem to enable record button when stop button is clicked.单击停止按钮时,您似乎没有启用录制按钮。 Write

record.setEnabled(true);

in the onClick() method implementation of stop button.在停止按钮的 onClick() 方法实现中。

Another case is when stop button is clicked you are setting myAudioRecorder = null .另一种情况是单击停止按钮时您正在设置myAudioRecorder = null If after this record button is clicked you will get a NullPointerException on this statement如果单击此记录按钮后,您将在此语句上获得 NullPointerException

myAudioRecorder.prepare() //exception

Solution will be to remove the statement of setting myAudioRecorder to null in onClick() implementation of stop.解决方案是在 stop 的 onClick() 实现中删除将 myAudioRecorder 设置为 null 的语句。

Another problem comes because of this statement myAudioRecorder.release() .另一个问题是因为这个语句myAudioRecorder.release() You can't get back the previous instance of MediaRecorder once you have released the resource.释放资源后,您将无法取回MediaRecorder的前一个实例。 Either reinitialize myAudioRecorder each time you record or do not release the resource after stop has been clicked.每次录制时重新初始化myAudioRecorder或在单击停止后不释放资源。 To look at MediaRecorder lifecycle see this.要查看MediaRecorder生命周期, 请参阅此内容。

Here is a reference code you can look and understand.这是您可以查看和理解的参考代码。 Please catch exceptions wherever required.请在需要的地方捕获异常。

//package name
//imports
public class RecordPlayActivity extends AppCompatActivity implements View.OnClickListener {
// declare buttons here
private MediaRecorder myAudioRecorder;
private String recordOutputFile;
private MediaPlayer mediaPlayer;

@Override
public void onCreate(Bundle savedInstanceState){
    super.onCreate(null);
    setContentView(R.layout.layout_name);
    //find buttons view by Id here
    record.setOnClickListener(this);
    stop.setOnClickListener(this);
    play.setOnClickListener(this);
    recordOutputFile = Environment.getExternalStorageDirectory().getAbsolutePath() + "/recording.3gp";
    myAudioRecorder = new MediaRecorder();
    myAudioRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    myAudioRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
    myAudioRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);
    myAudioRecorder.setOutputFile(recordOutputFile);
    mediaPlayer = new MediaPlayer();
    mediaPlayer.setDataSource(recordOutputFile);
    //Initial condition
    //stop.setEnabled(false);   //not required as stop can be made always enabled
    play.setEnabled(false);
}

@Override
public void onClick(View view){
    switch(view.getId()){
        case R.id.idForRecord:
            myAudioRecorder.prepare();
            myAudioRecorder.start();
            //Recording started
            record.setEnabled(false);
            // don't make play enabled cause you dont want to play
            // and record at same time without stopping record.
            play.setEnabled(false); //required because play can get enabled from stop but it should not remain when recording
            break;
        case R.id.idForStop:
            //if clicked after record
            myAudioRecorder.stop();
            myAudioRecorder.reset();
            //if clicked after play
            if(mediaPlayer.isLooping()) {
                mediaPlayer.stop();
            }
            //recording stopped and saved;
            record.setEnabled(true);
            play.setEnabled(true);
            break;
        case R.id.idForPlay:
            mediaPlayer.prepare();
            mediaPlayer.start();
            //playing
            record.setEnabled(false); // you dont wanna play and record at same time
            break;
        default:
    }
}

}` }`

Hope these all solves your problem.希望这些都能解决你的问题。

It's crashing because outputFile = Environment.getExternalStorageDirectory().getAbsolutePath() + "/recording.3gp" ;它崩溃是因为 outputFile = Environment.getExternalStorageDirectory().getAbsolutePath() + "/recording.3gp" ; directs to top directory od Android OS ...指向顶级目录 od Android OS ...

If you use this path Environment.getExternalStorageDirectory()+File.separator+"sounds" "/recording.3gp" then your recording will be going into one level down directory "sounds" into directory sounds .如果您使用此路径 Environment.getExternalStorageDirectory()+File.separator+"sounds" "/recording.3gp" 那么您的录音将进入下一级目录 "sounds" 进入目录 sounds 。

App will not crash if you recording is in folder down from top level path ...如果您的录音位于顶级路径下方的文件夹中,则应用程序不会崩溃...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM