Android MediaRecorder 在启动时崩溃
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10340400/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
MediaRecorder crashes on start
提问by eric.itzhak
i've searched many topics but no straight answer.
我搜索了很多主题,但没有直接的答案。
I have this code :
我有这个代码:
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setOutputFile(mFileName);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
if(!mStartRecording)
{
btn.setText("Stop Recording");
try {
recorder.prepare();
} catch (IOException e) {
e.printStackTrace();
}
recorder.start();
mStartRecording = true;
}
else
{
btn.setText("Start Recording");
mStartRecording = false;
recorder.stop();
recorder.reset();
recorder.release();
recorder = null;
}
And i've added :
我补充说:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
(saw somewhere that adding STORAGE solved it, no good for me)
(看到某处添加 STORAGE 解决了它,对我没有好处)
I'm developing on API Level 7 (Android 2.1)
我正在开发 API 级别 7(Android 2.1)
stack trace says "start faild" Stack trace :
堆栈跟踪显示“启动失败”堆栈跟踪:
04-26 19:27:41.955: D/dalvikvm(890): GC freed 809 objects / 58272 bytes in 433ms
04-26 19:27:44.772: D/dalvikvm(890): GC freed 95 objects / 3936 bytes in 371ms
04-26 19:28:54.973: E/MediaRecorder(890): start failed: -1
04-26 19:28:54.993: D/AndroidRuntime(890): Shutting down VM
04-26 19:28:54.993: W/dalvikvm(890): threadid=3: thread exiting with uncaught exception (group=0x4001b188)
04-26 19:28:54.993: E/AndroidRuntime(890): Uncaught handler: thread main exiting due to uncaught exception
04-26 19:28:55.105: E/AndroidRuntime(890): java.lang.IllegalStateException: Could not execute method of the activity
04-26 19:28:55.105: E/AndroidRuntime(890): at android.view.View.onClick(View.java:2031)
04-26 19:28:55.105: E/AndroidRuntime(890): at android.view.View.performClick(View.java:2364)
04-26 19:28:55.105: E/AndroidRuntime(890): at android.view.View.onTouchEvent(View.java:4179)
04-26 19:28:55.105: E/AndroidRuntime(890): at android.widget.TextView.onTouchEvent(TextView.java:6541)
04-26 19:28:55.105: E/AndroidRuntime(890): at android.view.View.dispatchTouchEvent(View.java:3709)
04-26 19:28:55.105: E/AndroidRuntime(890): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:884)
04-26 19:28:55.105: E/AndroidRuntime(890): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:884)
04-26 19:28:55.105: E/AndroidRuntime(890): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:884)
04-26 19:28:55.105: E/AndroidRuntime(890): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:884)
04-26 19:28:55.105: E/AndroidRuntime(890): at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1659)
04-26 19:28:55.105: E/AndroidRuntime(890): at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1107)
04-26 19:28:55.105: E/AndroidRuntime(890): at android.app.Activity.dispatchTouchEvent(Activity.java:2061)
04-26 19:28:55.105: E/AndroidRuntime(890): at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1643)
04-26 19:28:55.105: E/AndroidRuntime(890): at android.view.ViewRoot.handleMessage(ViewRoot.java:1691)
04-26 19:28:55.105: E/AndroidRuntime(890): at android.os.Handler.dispatchMessage(Handler.java:99)
04-26 19:28:55.105: E/AndroidRuntime(890): at android.os.Looper.loop(Looper.java:123)
04-26 19:28:55.105: E/AndroidRuntime(890): at android.app.ActivityThread.main(ActivityThread.java:4363)
04-26 19:28:55.105: E/AndroidRuntime(890): at java.lang.reflect.Method.invokeNative(Native Method)
04-26 19:28:55.105: E/AndroidRuntime(890): at java.lang.reflect.Method.invoke(Method.java:521)
04-26 19:28:55.105: E/AndroidRuntime(890): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
04-26 19:28:55.105: E/AndroidRuntime(890): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
04-26 19:28:55.105: E/AndroidRuntime(890): at dalvik.system.NativeStart.main(Native Method)
04-26 19:28:55.105: E/AndroidRuntime(890): Caused by: java.lang.reflect.InvocationTargetException
04-26 19:28:55.105: E/AndroidRuntime(890): at shibby.whisper.WhisperGameActivity.recordAudio(WhisperGameActivity.java:94)
04-26 19:28:55.105: E/AndroidRuntime(890): at java.lang.reflect.Method.invokeNative(Native Method)
04-26 19:28:55.105: E/AndroidRuntime(890): at java.lang.reflect.Method.invoke(Method.java:521)
04-26 19:28:55.105: E/AndroidRuntime(890): at android.view.View.onClick(View.java:2026)
04-26 19:28:55.105: E/AndroidRuntime(890): ... 21 more
04-26 19:28:55.105: E/AndroidRuntime(890): Caused by: java.lang.RuntimeException: start failed.
04-26 19:28:55.105: E/AndroidRuntime(890): at android.media.MediaRecorder.start(Native Method)
04-26 19:28:55.105: E/AndroidRuntime(890): ... 25 more
04-26 19:28:55.223: I/dalvikvm(890): threadid=7: reacting to signal 3
04-26 19:28:55.335: I/dalvikvm(890): Wrote stack trace to '/data/anr/traces.txt'
04-26 19:28:57.123: I/Process(890): Sending signal. PID: 890 SIG: 9
Please help.
请帮忙。
采纳答案by Snicolas
Ok, I got it. I guess you initialized mStartRecording to true.
好,我知道了。我猜你将 mStartRecording 初始化为 true。
Thus your if
is going into the else
block. In it, you stop a brand new instance of MediaRecorder and the state diagram doesn't allow that.
因此,您if
将进入该else
块。在其中,您停止了一个全新的 MediaRecorder 实例,状态图不允许这样做。
Make your media recorder a field of your class. And initialize properly your mStartRecording boolean variable to false. Re instanciate your media recorder only if your field is null.
让您的媒体录音机成为您班级的一个领域。并将您的 mStartRecording 布尔变量正确初始化为 false。仅当您的字段为空时才重新实例化您的媒体记录器。
if( recorder == null ) {
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setOutputFile(mFileName);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
}//if
if(!mStartRecording) {
btn.setText("Stop Recording");
try {
recorder.prepare();
recorder.start();
mStartRecording = true;
} catch (IOException e) {
e.printStackTrace();
}//catch
} else {
btn.setText("Start Recording");
mStartRecording = false;
recorder.stop();
recorder.reset();
recorder.release();
recorder = null;
}//else
回答by Anurag Ramdasan
Try putting the start
function in the same block as prepare
function. maybe there's an exception blocking prepare from executing and goes directly to start thus causing an IllegalStateException
.
尝试将start
函数放在与函数相同的块中prepare
。也许有一个异常阻止准备执行并直接启动,从而导致IllegalStateException
.
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(output_formats[currentFormat]);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(getFilename());
try {
recorder.prepare();
recorder.start();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
回答by minesh..
i am using the following code,works perfectly for me..
我正在使用以下代码,非常适合我..
protected void startRecording() {
// TODO Auto-generated method stub
i++;
mFileName = Environment.getExternalStorageDirectory().getAbsolutePath();
mFileName += "/audiorecordtest"+i+".3gp";
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setOutputFile(mFileName);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
try {
recorder.prepare();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
Toast.makeText(getApplicationContext(), "IllegalStateException called", Toast.LENGTH_LONG).show();
} catch (IOException e) {
// TODO Auto-generated catch block
Toast.makeText(getApplicationContext(), "prepare() failed", Toast.LENGTH_LONG).show();
}
recorder.start();
}
private void stopRecording() {
recorder.stop();
recorder.release();
recorder = null;
}
回答by hatiboy
These methods must arrange the order it will run. Here:
这些方法必须按照它运行的顺序进行安排。这里:
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setOutputFile(mFileName);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
回答by romeo14
I had the same problem. This is because I had missed a slash while setting the filename for the recorded audio.
我有同样的问题。这是因为我在为录制的音频设置文件名时遗漏了一个斜线。
change
改变
this.fileName = Environment.getExternalStorageDirectory().getAbsolutePath();
this.fileName += "yourfilename.3gp";
to
到
this.fileName = Environment.getExternalStorageDirectory().getAbsolutePath();
this.fileName += "/yourfilename.3gp";
回答by Pir Fahim Shah
I had same problem because of my SurfaceView has been made invisible. So make it Visible
我遇到了同样的问题,因为我的 SurfaceView 已不可见。所以让它可见
mSurfaceView.setVisibility(View.VISIBLE);
回答by Ali Bagheri
Must first call setOutputFile()
, and then call other methods.
必须先调用setOutputFile()
,然后再调用其他方法。
and you must create file before all.
并且您必须首先创建文件。
回答by Snicolas
Try to start your recorder only when it is prepared :
尝试仅在准备好时启动您的录音机:
try {
recorder.prepare();
recorder.start();
mStartRecording = true;
} catch (IOException e) {
Log.e( LOG_TAG, "Error when preparing or starting recorder", e);
}