问题描述
为了更好地理解Android中的音频录制和播放,我在android开发教程
因此,为了确保我们应该为
为了安全地停止或释放记录器相关资源,我们必须确保记录器已被注视.
recorder.start();//现在开始记录
输入您的特定代码
boolean isRecording = false;私人无效startRecording(){记录器=新的MediaRecorder();records.setAudioSource(MediaRecorder.AudioSource.MIC);records.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);records.setOutputFile(fileName);System.out.println(fileName);records.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);尝试 {records.prepare();records.start();isRecording = true;} catch(IOException e){Log.e(LOG_TAG,"prepare()失败"));//e.printStackTrace();}}....私人无效stopRecording(){if(isRecording){records.stop();}records.reset();//您可以通过返回setAudioSource()步骤来重用该对象records.release();//现在无法重用该对象isRecording = false;}
如果我们处于录制状态,请停止它,然后释放它,否则就释放它.
To get a better understanding of audio recording and playback in Android, I've implemented a clone of the code in the android dev tutorial https://developer.android.com/guide/topics/media/mediarecorder#sample-code
No errors occur upon starting the recording, however, I have yet to verify if any recording is actually taking place. Then when I stop recording, the app crashes to the previous activity and on a subsequent attempt the "app keeps crashing" dialog pops up and the app exits.
I have <uses-permission android:name="android.permission.RECORD_AUDIO" />
in the AndroidManifest
private void onRecord(boolean start) {
if (start) {
startRecording();
} else {
stopRecording(); // Line 53 //
}
}
private void startRecording() {
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setOutputFile(fileName);
System.out.println(fileName);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
try {
recorder.prepare();
} catch (IOException e) {
Log.e(LOG_TAG, "prepare() failed");
//e.printStackTrace();
}
}
private void stopRecording() {
recorder.stop(); // Line 98 //
recorder.release();
recorder = null;
}
class RecordButton extends AppCompatButton {
boolean mStartRecording = true;
OnClickListener clicker = new OnClickListener() {
public void onClick(View v) {
onRecord(mStartRecording);
if(mStartRecording) {
setText(R.string.stop_recording);
} else {
setText(R.string.start_recording);
}
mStartRecording = !mStartRecording;
}
};
public RecordButton(Context ctx){
super(ctx);
setText(R.string.start_recording);
setOnClickListener(clicker);
}
}
Logcat output:
2020-02-14 10:57:09.789 23619-23619/? E/Zygote: accessInfo : 1
2020-02-14 10:57:09.820 23619-23619/? E/.xxxxxx.xxxxxx: Unknown bits set in runtime_flags: 0x8000
2020-02-14 10:57:12.925 23619-23619/xx.xxxxxxx.xxxxxx.xxxxxxx E/MediaRecorder: stop called in an invalid state: 8
2020-02-14 10:57:12.927 23619-23619/xx.xxxxxxx.xxxxxx.xxxxxxx E/AndroidRuntime: FATAL EXCEPTION: main
Process: xx.xxxxxxx.xxxxxx.xxxxxxx, PID: 23619
java.lang.IllegalStateException
at android.media.MediaRecorder._stop(Native Method)
at android.media.MediaRecorder.stop(MediaRecorder.java:1440)
at xx.xxxxxxx.xxxxxx.xxxxxxx.RecordActivity.stopRecording(RecordActivity.java:98)
at xx.xxxxxxx.xxxxxx.xxxxxxx.RecordActivity.onRecord(RecordActivity.java:53)
at xx.xxxxxxx.xxxxxx.xxxxxxx.RecordActivity.access$000(RecordActivity.java:21)
at xx.xxxxxxx.xxxxxx.xxxxxxx.RecordActivity$RecordButton$1.onClick(RecordActivity.java:108)
at android.view.View.performClick(View.java:7866)
at android.widget.TextView.performClick(TextView.java:14952)
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:7811)
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:1076)
I can provide any relevant additional code or details if needed
EDITPermission is requested with the following:
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode){
case REQUEST_RECORD_AUDIO_PERMISSION:
permissionToRecordAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
break;
}
if (!permissionToRecordAccepted ) finish();
}
and inside onCreate():
ActivityCompat.requestPermissions(this, permissions, REQUEST_RECORD_AUDIO_PERMISSION);
EDIT 2 *I've verified that the audio recording file is being created but is 0 B in size
Media Player
in the below flowchart, stop()
valid states are {Prepared, Started, Stopped, Paused, PlaybackCompleted}
. other states(Idle,Initialized,Error) are NOT valid states in order to call stop()
. otherwise, IllegalStateException
thrown.
Therefore, for Ensure we should set states listeners for the MediaPlayer. Because, Prepared
state is initialized earlier then by setOnPreparedListener
for player
we can safely stop player.
...
boolean isPrepared = false;
...
recorder.setOnPreparedListener ....
{
...
isPrepared = true;
...
}
...
private void stopRecording() {
if(isPrepared){
player.stop();
...
}
}
i made the code summarized for better understanding.
Media Recorder
in the below flowchart, stop()
is available only if you are in recording state. otherwise, calling stop()
throws IllegalStateException
.
in order to safely stop or release recorder related resources we have to make sure recorder has been stared.
recorder.start(); // Recording is now started
for your specific code
boolean isRecording = false;
private void startRecording() {
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setOutputFile(fileName);
System.out.println(fileName);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
try {
recorder.prepare();
recorder.start();
isRecording = true;
} catch (IOException e) {
Log.e(LOG_TAG, "prepare() failed");
//e.printStackTrace();
}
}
....
private void stopRecording() {
if(isRecording){
recorder.stop();
}
recorder.reset(); // You can reuse the object by going back to setAudioSource() step
recorder.release(); // Now the object cannot be reused
isRecording = false;
}
if we are in recording state stop it then release it otherwise just release it.
这篇关于为什么停止MediaRecorder时会收到IllegalStateException?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!