问题
I want to make a voice recorder app but it crashes when i click the "Start Recording" button. I get an error saying java.lang.IllegalStateException at android.media.MediaRecorder.start(Native Method). Ive also attached the log.
package com.example.sahil.chuckit;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.app.Activity;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.os.Environment;
import java.io.File;
public class MainActivity extends Activity {
private static Button submit;
private static Button submit2;
private static Button submit3;
private static Button submit4;
private MediaPlayer mediaPlayer;
private MediaRecorder recorder;
private String output_file;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
output_file = Environment.getExternalStorageState() + "/audiorecorder.3gpp";
OnClickButtonListener();OnClickButtonListener1();
OnClickButtonListener3();OnClickButtonListener4();
}
public void OnClickButtonListener(){
submit =(Button)findViewById(R.id.button);
submit.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
beginRecording();
}
}
);
}
public void OnClickButtonListener1(){
submit2 =(Button)findViewById(R.id.button2);
submit2.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
stopRecording();
}
}
);
}
public void OnClickButtonListener3(){
submit3 =(Button)findViewById(R.id.button3);
submit3.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
playRecording();
} catch (Exception e) {
e.printStackTrace();
}
}
}
);
}
public void OnClickButtonListener4(){
submit4 =(Button)findViewById(R.id.button4);
submit4.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
stopPlayback();
}
}
);
}
private void ditchMediaRecorder() {
if (recorder != null)
recorder.release();
}
private void beginRecording() {
ditchMediaRecorder();
File outFile=new File(output_file);
if (outFile.exists())
{ outFile.delete();}
recorder=new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(output_file);
recorder.start();
}
private void stopRecording() {
if(recorder!=null)
recorder.stop();
}
private void playRecording() throws Exception {
ditchMediaPlayer();
mediaPlayer=new MediaPlayer();
mediaPlayer.setDataSource(output_file);
mediaPlayer.prepare();
mediaPlayer.start();
}
private void ditchMediaPlayer() {
if(mediaPlayer!=null)
{
try{
mediaPlayer.release();
}catch (Exception e){
e.printStackTrace();
}
}
}
private void stopPlayback() {
if (mediaPlayer!=null)
mediaPlayer.stop();
}
}
Logcat:
LOG:06-30 05:11:12.603 24621-24621/com.example.sahil.chuckit E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.sahil.chuckit, PID: 24621 java.lang.IllegalStateException
at android.media.MediaRecorder.start(Native Method)
at com.example.sahil.chuckit.MainActivity.beginRecording(MainActivity.java:111)
at com.example.sahil.chuckit.MainActivity.access$000(MainActivity.java:22)
at com.example.sahil.chuckit.MainActivity$1.onClick(MainActivity.java:46)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
06-30 05:11:14.891 24621-24621/com.example.sahil.chuckit I/Process: Sending signal. PID: 24621 SIG: 9
回答1:
you are forgetting to call recorder.prepare()
before recordeer.start()
function in your beginRecording
function.
Prepare function will take care about lot of things like conversion of analog data to digital audio for compresion and where to store the file etc
回答2:
You have to take into consideration, that MediaRecorder as well as MediaPlayer has their state machines, which obligate you to do some action in specific sequence.
Here you tried to start recording withou preparing MediaRecorder
. Call
recorder.prepare();
Before:
recorder.start();
回答3:
Call this after setOutFormat() but before prepare().
this is just what my android studio docs dialog says while i write this method name.
the point is that you should call this method just before prepare().
here is an example:
private void startRecording() {
mediaRecorder = new MediaRecorder();
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
File outputFolder = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/MediaMaster/Dub/");
Log.i(TAG, "startRecording: creating output file " + outputFolder.mkdirs());
File output = new File(outputFolder.getAbsolutePath()+"out" + new Date().getTime() + ".3gpp");
mediaRecorder.setOutputFile(output.getAbsolutePath());
mediaRecorder.setMaxDuration(3000);
try {
mediaRecorder.prepare();
} catch (IOException e) {
Log.e(TAG, "startRecording: ", e);
}
mediaRecorder.start();
}
来源:https://stackoverflow.com/questions/38120455/java-lang-illegalstateexception-at-android-media-mediarecorder-startnative-meth