http://blog.csdn.net/cxf7394373/article/details/8313980
android開發文檔中有一個關于錄音的類MediaRecord,一張圖介紹了基本的流程:
給出了一個常用的例子: [java] view plain copy
- MediaRecorder recorder = new MediaRecorder();
- recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
- recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
- recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
- recorder.setOutputFile(PATH_NAME);
- recorder.prepare();
- recorder.start(); // Recording is now started
- ...
- recorder.stop();
- recorder.reset(); // You can reuse the object by going back to setAudioSource() step
- recorder.release(); // Now the object cannot be reused
我在這裡實作了一個簡單的程式,過程和上述類似,錄音以及錄音的播放。 1.基本界面如下:
2.工程中各檔案内容如下: 2.1 Activity——RecordActivity [java] view plain copy
- package com.cxf;
- import java.io.IOException;
- import android.app.Activity;
- import android.media.MediaPlayer;
- import android.media.MediaRecorder;
- import android.os.Bundle;
- import android.os.Environment;
- import android.util.Log;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- public class RecordActivity extends Activity {
- private static final String LOG_TAG = "AudioRecordTest";
- //語音檔案儲存路徑
- private String FileName = null;
- //界面控件
- private Button startRecord;
- private Button startPlay;
- private Button stopRecord;
- private Button stopPlay;
- //語音操作對象
- private MediaPlayer mPlayer = null;
- private MediaRecorder mRecorder = null;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- //開始錄音
- startRecord = (Button)findViewById(R.id.startRecord);
- startRecord.setText(R.string.startRecord);
- //綁定監聽器
- startRecord.setOnClickListener(new startRecordListener());
- //結束錄音
- stopRecord = (Button)findViewById(R.id.stopRecord);
- stopRecord.setText(R.string.stopRecord);
- stopRecord.setOnClickListener(new stopRecordListener());
- //開始播放
- startPlay = (Button)findViewById(R.id.startPlay);
- startPlay.setText(R.string.startPlay);
- //綁定監聽器
- startPlay.setOnClickListener(new startPlayListener());
- //結束播放
- stopPlay = (Button)findViewById(R.id.stopPlay);
- stopPlay.setText(R.string.stopPlay);
- stopPlay.setOnClickListener(new stopPlayListener());
- //設定sdcard的路徑
- FileName = Environment.getExternalStorageDirectory().getAbsolutePath();
- FileName += "/audiorecordtest.3gp";
- }
- //開始錄音
- class startRecordListener implements OnClickListener{
- @Override
- public void onClick(View v) {
- // TODO Auto-generated method stub
- mRecorder = new MediaRecorder();
- mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
- mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
- mRecorder.setOutputFile(FileName);
- mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
- try {
- mRecorder.prepare();
- } catch (IOException e) {
- Log.e(LOG_TAG, "prepare() failed");
- }
- mRecorder.start();
- }
- }
- //停止錄音
- class stopRecordListener implements OnClickListener{
- @Override
- public void onClick(View v) {
- // TODO Auto-generated method stub
- mRecorder.stop();
- mRecorder.release();
- mRecorder = null;
- }
- }
- //播放錄音
- class startPlayListener implements OnClickListener{
- @Override
- public void onClick(View v) {
- // TODO Auto-generated method stub
- mPlayer = new MediaPlayer();
- try{
- mPlayer.setDataSource(FileName);
- mPlayer.prepare();
- mPlayer.start();
- }catch(IOException e){
- Log.e(LOG_TAG,"播放失敗");
- }
- }
- }
- //停止播放錄音
- class stopPlayListener implements OnClickListener{
- @Override
- public void onClick(View v) {
- // TODO Auto-generated method stub
- mPlayer.release();
- mPlayer = null;
- }
- }
- }
2.2 main.xml [html] view plain copy
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:orientation="vertical" >
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="@string/hello" />
- <Button
- android:id="@+id/startRecord"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- />
- <Button
- android:id="@+id/stopRecord"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- />
- <Button
- android:id="@+id/startPlay"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- />
- <Button
- android:id="@+id/stopPlay"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- />
- </LinearLayout>
2.3 Manifest.xml [html] view plain copy
- <?xml version="1.0" encoding="utf-8"?>
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.cxf"
- android:versionCode="1"
- android:versionName="1.0" >
- <uses-sdk android:minSdkVersion="4" />
- <application
- android:icon="@drawable/ic_launcher"
- android:label="@string/app_name" >
- <activity
- android:name=".RecordActivity"
- android:label="@string/app_name" >
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- </application>
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
- <uses-permission android:name="android.permission.RECORD_AUDIO" />
- </manifest>
2.4 string.xml [html] view plain copy
- <?xml version="1.0" encoding="utf-8"?>
- <resources>
- <string name="hello"></string>
- <string name="app_name">Record</string>
- <string name="startRecord">開始錄音</string>
- <string name="stopRecord">結束錄音</string>
- <string name="startPlay">開始播放</string>
- <string name="stopPlay">結束播放</string>
- </resources>
今天在調用MediaRecorder.stop(),報錯了,Java.lang.RuntimeException: stop failed.
[html] view plain copy
- E/AndroidRuntime(7698): Cause by: java.lang.RuntimeException: stop failed.
- E/AndroidRuntime(7698): at android.media.MediaRecorder.stop(Native Method)
- E/AndroidRuntime(7698): at com.tintele.sos.VideoRecordService.stopRecord(VideoRecordService.java:298)
報錯代碼如下:
[java] view plain copy
- if (mediarecorder != null) {
- mediarecorder.stop();
- mediarecorder.release();
- mediarecorder = null;
- if (mCamera != null) {
- mCamera.release();
- mCamera = null;
- }
- }
stop()方法源代碼如下:
[java] view plain copy
- public native void stop() throws IllegalStateException;
源代碼中說了:Note that a RuntimeException is intentionally thrown to the application, if no valid audio/video data has been received when stop() is called. This happens if stop() is called immediately after start().The failure lets the application take action accordingly to clean up the output file (delete the output file, for instance), since the output file is not properly constructed when this happens.
現在,在mediarecorder.stop();這一句報錯了,現在在mediarecorder.stop();這句之前加幾句就不會報錯了
mediarecorder.setOnErrorListener(null);
mediarecorder.setOnInfoListener(null);
mediarecorder.setPreviewDisplay(null);
改後代碼如下:
[java] view plain copy
-
- if (mediarecorder != null) {
- //added by ouyang start
- try {
- //下面三個參數必須加,不加的話會奔潰,在mediarecorder.stop();
- //報錯為:RuntimeException:stop failed
- mediarecorder.setOnErrorListener(null);
- mediarecorder.setOnInfoListener(null);
- mediarecorder.setPreviewDisplay(null);
- mediarecorder.stop();
- } catch (IllegalStateException e) {
- // TODO: handle exception
- Log.i("Exception", Log.getStackTraceString(e));
- }catch (RuntimeException e) {
- // TODO: handle exception
- Log.i("Exception", Log.getStackTraceString(e));
- }catch (Exception e) {
- // TODO: handle exception
- Log.i("Exception", Log.getStackTraceString(e));
- }
- //added by ouyang end
- mediarecorder.release();
- mediarecorder = null;
- if (mCamera != null) {
- mCamera.release();
- mCamera = null;
- }
- }