我正在学习android开发,我正在使用mediarecorder类来录制音频。logcat说应用程序在stop()方法中崩溃,并抛出illegalstateexception。我不明白为什么它会崩溃,我在开始之前调用stop方法。
public class MainActivity extends AppCompatActivity {
private MediaRecorder grabacion;
private String archivoSalida = null;
private Button btn_recorder;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_recorder = (Button)findViewById(R.id.btn_rec);
if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO,}, 1000);
}
}
public void Recorder(View view){
if(grabacion == null){
archivoSalida = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Grabacion.mp3";
grabacion = new MediaRecorder();
grabacion.setAudioSource(MediaRecorder.AudioSource.MIC);
grabacion.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
grabacion.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);
grabacion.setOutputFile(archivoSalida);
try{
grabacion.prepare();
grabacion.start();
} catch (IOException e){
}
btn_recorder.setBackgroundResource(R.drawable.rec);
Toast.makeText(getApplicationContext(), "Grabando...", Toast.LENGTH_SHORT).show();
} else if(grabacion != null){
grabacion.stop();
grabacion.release();
grabacion = null;
btn_recorder.setBackgroundResource(R.drawable.stop_rec);
Toast.makeText(getApplicationContext(), "Grabación finalizada", Toast.LENGTH_SHORT).show();
}
}
public void reproducir(View view) {
MediaPlayer mediaPlayer = new MediaPlayer();
try {
mediaPlayer.setDataSource(archivoSalida);
mediaPlayer.prepare();
} catch (IOException e){
}
mediaPlayer.start();
Toast.makeText(getApplicationContext(), "Reproduciendo audio", Toast.LENGTH_SHORT).show();
}}
这是清单文件:
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
logcat说:
E/MediaRecorder: stop called in an invalid state: 4
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.recorder, PID: 5386
java.lang.IllegalStateException: Could not execute method for android:onClick
at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:414)
at android.view.View.performClick(View.java:7870)
at android.widget.TextView.performClick(TextView.java:14970)
at android.view.View.performClickInternal(View.java:7839)
at android.view.View.access$3600(View.java:886)
at android.view.View$PerformClick.run(View.java:29363)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:7948)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1075)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:409)
at android.view.View.performClick(View.java:7870)
at android.widget.TextView.performClick(TextView.java:14970)
at android.view.View.performClickInternal(View.java:7839)
at android.view.View.access$3600(View.java:886)
at android.view.View$PerformClick.run(View.java:29363)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:7948)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1075)
Caused by: java.lang.IllegalStateException
at android.media.MediaRecorder._stop(Native Method)
at android.media.MediaRecorder.stop(MediaRecorder.java:1440)
at com.example.recorder.MainActivity.Recorder(MainActivity.java:55)
at java.lang.reflect.Method.invoke(Native Method)
at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:409)
at android.view.View.performClick(View.java:7870)
at android.widget.TextView.performClick(TextView.java:14970)
at android.view.View.performClickInternal(View.java:7839)
at android.view.View.access$3600(View.java:886)
at android.view.View$PerformClick.run(View.java:29363)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:7948)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1075)
I/Process: Sending signal. PID: 5386 SIG: 9
谢谢!
1条答案
按热度按时间z18hc3ub1#
文件
stop()
方法声明它将抛出IllegalStateException
如果在start()之前调用因为这似乎是唯一一次抛出这个错误,所以这很可能是您的情况下发生的事情。
看看你的眼睛
Recorder()
方法。唯一的时间stop()
当变量不为null时,将调用。这意味着您的示例已正确初始化。但是,由于抛出了异常,这意味着即使您的变量引用的是MediaRecorder
,它没有启动。要找出原因,请看一下启动您的
MediaRecorder
:当它被放置在try-catch构造中时,catch块实际上并不包含任何代码,从而导致任何错误都被忽略。因此,你遇到的问题是
grabacion.prepare();
或者grabacion.start();
不成功导致记录器无法启动。鉴于此
start()
只会抛出一个IllegalStateException
根据其文件prepare()
应该是问题的原因。这也符合我自己的经验,因为打电话时有很多地方会出错prepare()
. 以下是根据文档中的描述所做的:准备记录器开始捕获和编码数据。必须在设置所需的音频和视频源、编码器、文件格式等之后,但在start()之前调用此方法。
所以,正如你所知,现在要为我找出确切的原因并不容易。不过,我要补充的是
Environment.getExternalStorageDirectory()
从api 29开始,它就被弃用以改善用户隐私。虽然这可能是你的问题,但我不能完全肯定。为了准确地找出错误的原因,你应该利用它
IOException
你在试着接球。例如,您可以记录其堆栈跟踪,以了解有关该问题的更多信息。