天天看點

[Android] 錄音與播放錄音實作

http://blog.csdn.net/cxf7394373/article/details/8313980

android開發文檔中有一個關于錄音的類MediaRecord,一張圖介紹了基本的流程:

[Android] 錄音與播放錄音實作

給出了一個常用的例子: [java]  view plain  copy  

  1. MediaRecorder recorder = new MediaRecorder();  
  2.  recorder.setAudioSource(MediaRecorder.AudioSource.MIC);  
  3.  recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);  
  4.  recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);  
  5.  recorder.setOutputFile(PATH_NAME);  
  6.  recorder.prepare();  
  7.  recorder.start();   // Recording is now started  
  8.  ...  
  9.  recorder.stop();  
  10.  recorder.reset();   // You can reuse the object by going back to setAudioSource() step  
  11.  recorder.release(); // Now the object cannot be reused  

我在這裡實作了一個簡單的程式,過程和上述類似,錄音以及錄音的播放。 1.基本界面如下:

[Android] 錄音與播放錄音實作

  2.工程中各檔案内容如下:   2.1 Activity——RecordActivity [java]  view plain  copy  

  1. package com.cxf;  
  2. import java.io.IOException;  
  3. import android.app.Activity;  
  4. import android.media.MediaPlayer;  
  5. import android.media.MediaRecorder;  
  6. import android.os.Bundle;  
  7. import android.os.Environment;  
  8. import android.util.Log;  
  9. import android.view.View;  
  10. import android.view.View.OnClickListener;  
  11. import android.widget.Button;  
  12. public class RecordActivity extends Activity {  
  13.     private static final String LOG_TAG = "AudioRecordTest";  
  14.     //語音檔案儲存路徑  
  15.     private String FileName = null;  
  16.     //界面控件  
  17.     private Button startRecord;   
  18.     private Button startPlay;  
  19.     private Button stopRecord;  
  20.     private Button stopPlay;  
  21.     //語音操作對象  
  22.     private MediaPlayer mPlayer = null;  
  23.     private MediaRecorder mRecorder = null;  
  24.     @Override  
  25.     public void onCreate(Bundle savedInstanceState) {  
  26.         super.onCreate(savedInstanceState);  
  27.         setContentView(R.layout.main);  
  28.         //開始錄音  
  29.         startRecord = (Button)findViewById(R.id.startRecord);  
  30.         startRecord.setText(R.string.startRecord);  
  31.         //綁定監聽器  
  32.         startRecord.setOnClickListener(new startRecordListener());  
  33.         //結束錄音  
  34.         stopRecord = (Button)findViewById(R.id.stopRecord);  
  35.         stopRecord.setText(R.string.stopRecord);  
  36.         stopRecord.setOnClickListener(new stopRecordListener());  
  37.         //開始播放  
  38.         startPlay = (Button)findViewById(R.id.startPlay);  
  39.         startPlay.setText(R.string.startPlay);  
  40.         //綁定監聽器  
  41.         startPlay.setOnClickListener(new startPlayListener());  
  42.         //結束播放  
  43.         stopPlay = (Button)findViewById(R.id.stopPlay);  
  44.         stopPlay.setText(R.string.stopPlay);  
  45.         stopPlay.setOnClickListener(new stopPlayListener());  
  46.         //設定sdcard的路徑  
  47.         FileName = Environment.getExternalStorageDirectory().getAbsolutePath();  
  48.         FileName += "/audiorecordtest.3gp";  
  49.     }  
  50.     //開始錄音  
  51.     class startRecordListener implements OnClickListener{  
  52.         @Override  
  53.         public void onClick(View v) {  
  54.             // TODO Auto-generated method stub  
  55.              mRecorder = new MediaRecorder();  
  56.              mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);  
  57.              mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);  
  58.              mRecorder.setOutputFile(FileName);  
  59.              mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);  
  60.              try {  
  61.                  mRecorder.prepare();  
  62.              } catch (IOException e) {  
  63.                  Log.e(LOG_TAG, "prepare() failed");  
  64.              }  
  65.              mRecorder.start();  
  66.         }  
  67.     }  
  68.     //停止錄音  
  69.     class stopRecordListener implements OnClickListener{  
  70.         @Override  
  71.         public void onClick(View v) {  
  72.             // TODO Auto-generated method stub  
  73.              mRecorder.stop();  
  74.              mRecorder.release();  
  75.              mRecorder = null;  
  76.         }  
  77.     }  
  78.     //播放錄音  
  79.     class startPlayListener implements OnClickListener{  
  80.         @Override  
  81.         public void onClick(View v) {  
  82.             // TODO Auto-generated method stub  
  83.             mPlayer = new MediaPlayer();  
  84.             try{  
  85.                 mPlayer.setDataSource(FileName);  
  86.                 mPlayer.prepare();  
  87.                 mPlayer.start();  
  88.             }catch(IOException e){  
  89.                 Log.e(LOG_TAG,"播放失敗");  
  90.             }  
  91.         }  
  92.     }  
  93.     //停止播放錄音  
  94.     class stopPlayListener implements OnClickListener{  
  95.         @Override  
  96.         public void onClick(View v) {  
  97.             // TODO Auto-generated method stub  
  98.             mPlayer.release();  
  99.             mPlayer = null;  
  100.         }  
  101.     }  
  102. }  

 2.2 main.xml [html]  view plain  copy  

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="fill_parent"  
  4.     android:layout_height="fill_parent"  
  5.     android:orientation="vertical" >  
  6.     <TextView  
  7.         android:layout_width="fill_parent"  
  8.         android:layout_height="wrap_content"  
  9.         android:text="@string/hello" />  
  10.     <Button   
  11.         android:id="@+id/startRecord"  
  12.         android:layout_width="fill_parent"  
  13.         android:layout_height="wrap_content"  
  14.       />  
  15.     <Button   
  16.         android:id="@+id/stopRecord"  
  17.         android:layout_width="fill_parent"  
  18.         android:layout_height="wrap_content"  
  19.       />  
  20.     <Button   
  21.         android:id="@+id/startPlay"  
  22.         android:layout_width="fill_parent"  
  23.         android:layout_height="wrap_content"  
  24.       />  
  25.     <Button   
  26.         android:id="@+id/stopPlay"  
  27.         android:layout_width="fill_parent"  
  28.         android:layout_height="wrap_content"  
  29.       />  
  30. </LinearLayout>  

 2.3 Manifest.xml [html]  view plain  copy  

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     package="com.cxf"  
  4.     android:versionCode="1"  
  5.     android:versionName="1.0" >  
  6.     <uses-sdk android:minSdkVersion="4" />  
  7.     <application  
  8.         android:icon="@drawable/ic_launcher"  
  9.         android:label="@string/app_name" >  
  10.         <activity  
  11.             android:name=".RecordActivity"  
  12.             android:label="@string/app_name" >  
  13.             <intent-filter>  
  14.                 <action android:name="android.intent.action.MAIN" />  
  15.                 <category android:name="android.intent.category.LAUNCHER" />  
  16.             </intent-filter>  
  17.         </activity>  
  18.     </application>  
  19.     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />  
  20.     <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>  
  21.     <uses-permission android:name="android.permission.RECORD_AUDIO" />  
  22. </manifest>  

 2.4 string.xml [html]  view plain  copy  

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <resources>  
  3.     <string name="hello"></string>  
  4.     <string name="app_name">Record</string>  
  5.     <string name="startRecord">開始錄音</string>  
  6.     <string name="stopRecord">結束錄音</string>  
  7.     <string name="startPlay">開始播放</string>  
  8.     <string name="stopPlay">結束播放</string>  
  9. </resources> 

今天在調用MediaRecorder.stop(),報錯了,Java.lang.RuntimeException: stop failed.

[html]  view plain  copy  

  1. E/AndroidRuntime(7698): Cause by: java.lang.RuntimeException: stop failed.  
  2. E/AndroidRuntime(7698):            at android.media.MediaRecorder.stop(Native Method)  
  3. E/AndroidRuntime(7698):            at com.tintele.sos.VideoRecordService.stopRecord(VideoRecordService.java:298)  
[Android] 錄音與播放錄音實作

報錯代碼如下:

[java]  view plain  copy  

  1. if (mediarecorder != null) {  
  2.         mediarecorder.stop();  
  3.         mediarecorder.release();  
  4.         mediarecorder = null;  
  5.         if (mCamera != null) {  
  6.             mCamera.release();  
  7.             mCamera = null;  
  8.         }  
  9.     }  

stop()方法源代碼如下:

[java]  view plain  copy  

  1.     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  

    1. if (mediarecorder != null) {  
    2.             //added by ouyang start  
    3.             try {  
    4.                 //下面三個參數必須加,不加的話會奔潰,在mediarecorder.stop();  
    5.                 //報錯為:RuntimeException:stop failed  
    6.                 mediarecorder.setOnErrorListener(null);  
    7.                 mediarecorder.setOnInfoListener(null);    
    8.                 mediarecorder.setPreviewDisplay(null);  
    9.                 mediarecorder.stop();  
    10.             } catch (IllegalStateException e) {  
    11.                 // TODO: handle exception  
    12.                 Log.i("Exception", Log.getStackTraceString(e));  
    13.             }catch (RuntimeException e) {  
    14.                 // TODO: handle exception  
    15.                 Log.i("Exception", Log.getStackTraceString(e));  
    16.             }catch (Exception e) {  
    17.                 // TODO: handle exception  
    18.                 Log.i("Exception", Log.getStackTraceString(e));  
    19.             }  
    20.             //added by ouyang end  
    21.             mediarecorder.release();  
    22.             mediarecorder = null;  
    23.             if (mCamera != null) {  
    24.                 mCamera.release();  
    25.                 mCamera = null;  
    26.             }  
    27.         }