[Android] 录音与播放录音实现

Android录音与播放
本文介绍了一个使用Android平台上的MediaRecorder和MediaPlayer类实现录音与播放功能的简单程序。文章提供了完整的代码示例,包括Activity配置、界面布局定义及必要的权限设置,并针对MediaRecorder.stop()方法可能引发的异常给出了解决方案。

http://blog.youkuaiyun.com/cxf7394373/article/details/8313980

android开发文档中有一个关于录音的类MediaRecord,一张图介绍了基本的流程:

给出了一个常用的例子:
[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.基本界面如下:
 
2.工程中各文件内容如下:
  2.1 Activity——RecordActivity
[java]  view plain  copy
 
  1. package com.cxf;  
  2.   
  3. import java.io.IOException;  
  4.   
  5. import android.app.Activity;  
  6. import android.media.MediaPlayer;  
  7. import android.media.MediaRecorder;  
  8. import android.os.Bundle;  
  9. import android.os.Environment;  
  10. import android.util.Log;  
  11. import android.view.View;  
  12. import android.view.View.OnClickListener;  
  13. import android.widget.Button;  
  14.   
  15. public class RecordActivity extends Activity {  
  16.      
  17.     private static final String LOG_TAG = "AudioRecordTest";  
  18.     //语音文件保存路径  
  19.     private String FileName = null;  
  20.       
  21.     //界面控件  
  22.     private Button startRecord;   
  23.     private Button startPlay;  
  24.     private Button stopRecord;  
  25.     private Button stopPlay;  
  26.       
  27.     //语音操作对象  
  28.     private MediaPlayer mPlayer = null;  
  29.     private MediaRecorder mRecorder = null;  
  30.     /** Called when the activity is first created. */  
  31.     @Override  
  32.     public void onCreate(Bundle savedInstanceState) {  
  33.         super.onCreate(savedInstanceState);  
  34.         setContentView(R.layout.main);  
  35.           
  36.         //开始录音  
  37.         startRecord = (Button)findViewById(R.id.startRecord);  
  38.         startRecord.setText(R.string.startRecord);  
  39.         //绑定监听器  
  40.         startRecord.setOnClickListener(new startRecordListener());  
  41.           
  42.         //结束录音  
  43.         stopRecord = (Button)findViewById(R.id.stopRecord);  
  44.         stopRecord.setText(R.string.stopRecord);  
  45.         stopRecord.setOnClickListener(new stopRecordListener());  
  46.           
  47.         //开始播放  
  48.         startPlay = (Button)findViewById(R.id.startPlay);  
  49.         startPlay.setText(R.string.startPlay);  
  50.         //绑定监听器  
  51.         startPlay.setOnClickListener(new startPlayListener());  
  52.           
  53.         //结束播放  
  54.         stopPlay = (Button)findViewById(R.id.stopPlay);  
  55.         stopPlay.setText(R.string.stopPlay);  
  56.         stopPlay.setOnClickListener(new stopPlayListener());  
  57.           
  58.         //设置sdcard的路径  
  59.         FileName = Environment.getExternalStorageDirectory().getAbsolutePath();  
  60.         FileName += "/audiorecordtest.3gp";  
  61.     }  
  62.     //开始录音  
  63.     class startRecordListener implements OnClickListener{  
  64.   
  65.         @Override  
  66.         public void onClick(View v) {  
  67.             // TODO Auto-generated method stub  
  68.              mRecorder = new MediaRecorder();  
  69.              mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);  
  70.              mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);  
  71.              mRecorder.setOutputFile(FileName);  
  72.              mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);  
  73.              try {  
  74.                  mRecorder.prepare();  
  75.              } catch (IOException e) {  
  76.                  Log.e(LOG_TAG, "prepare() failed");  
  77.              }  
  78.              mRecorder.start();  
  79.         }  
  80.           
  81.     }  
  82.     //停止录音  
  83.     class stopRecordListener implements OnClickListener{  
  84.   
  85.         @Override  
  86.         public void onClick(View v) {  
  87.             // TODO Auto-generated method stub  
  88.              mRecorder.stop();  
  89.              mRecorder.release();  
  90.              mRecorder = null;  
  91.         }  
  92.           
  93.     }  
  94.     //播放录音  
  95.     class startPlayListener implements OnClickListener{  
  96.   
  97.         @Override  
  98.         public void onClick(View v) {  
  99.             // TODO Auto-generated method stub  
  100.             mPlayer = new MediaPlayer();  
  101.             try{  
  102.                 mPlayer.setDataSource(FileName);  
  103.                 mPlayer.prepare();  
  104.                 mPlayer.start();  
  105.             }catch(IOException e){  
  106.                 Log.e(LOG_TAG,"播放失败");  
  107.             }  
  108.         }  
  109.           
  110.     }  
  111.     //停止播放录音  
  112.     class stopPlayListener implements OnClickListener{  
  113.   
  114.         @Override  
  115.         public void onClick(View v) {  
  116.             // TODO Auto-generated method stub  
  117.             mPlayer.release();  
  118.             mPlayer = null;  
  119.         }  
  120.           
  121.     }  
  122. }  
 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.   
  7.     <TextView  
  8.         android:layout_width="fill_parent"  
  9.         android:layout_height="wrap_content"  
  10.         android:text="@string/hello" />  
  11.     <Button   
  12.         android:id="@+id/startRecord"  
  13.         android:layout_width="fill_parent"  
  14.         android:layout_height="wrap_content"  
  15.       />  
  16.     <Button   
  17.         android:id="@+id/stopRecord"  
  18.         android:layout_width="fill_parent"  
  19.         android:layout_height="wrap_content"  
  20.       />  
  21.     <Button   
  22.         android:id="@+id/startPlay"  
  23.         android:layout_width="fill_parent"  
  24.         android:layout_height="wrap_content"  
  25.       />  
  26.     <Button   
  27.         android:id="@+id/stopPlay"  
  28.         android:layout_width="fill_parent"  
  29.         android:layout_height="wrap_content"  
  30.       />  
  31. </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.   
  7.     <uses-sdk android:minSdkVersion="4" />  
  8.   
  9.     <application  
  10.         android:icon="@drawable/ic_launcher"  
  11.         android:label="@string/app_name" >  
  12.         <activity  
  13.             android:name=".RecordActivity"  
  14.             android:label="@string/app_name" >  
  15.             <intent-filter>  
  16.                 <action android:name="android.intent.action.MAIN" />  
  17.   
  18.                 <category android:name="android.intent.category.LAUNCHER" />  
  19.             </intent-filter>  
  20.               
  21.         </activity>  
  22.          
  23.     </application>  
  24.     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />  
  25.     <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>  
  26.     <uses-permission android:name="android.permission.RECORD_AUDIO" />  
  27. </manifest>  
 2.4 string.xml
[html]  view plain  copy
 
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <resources>  
  3.   
  4.   
  5.     <string name="hello"></string>  
  6.     <string name="app_name">Record</string>  
  7.     <string name="startRecord">开始录音</string>  
  8.     <string name="stopRecord">结束录音</string>  
  9.     <string name="startPlay">开始播放</string>  
  10.     <string name="stopPlay">结束播放</string>  
  11. </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)  



 

报错代码如下:

 

[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. /** 
  2.      * Stops recording. Call this after start(). Once recording is stopped, 
  3.      * you will have to configure it again as if it has just been constructed. 
  4.      * Note that a RuntimeException is intentionally thrown to the 
  5.      * application, if no valid audio/video data has been received when stop() 
  6.      * is called. This happens if stop() is called immediately after 
  7.      * start(). The failure lets the application take action accordingly to 
  8.      * clean up the output file (delete the output file, for instance), since 
  9.      * the output file is not properly constructed when this happens. 
  10.      * 
  11.      * @throws IllegalStateException if it is called before start() 
  12.      */  
  13.     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.               
    22.             mediarecorder.release();  
    23.             mediarecorder = null;  
    24.             if (mCamera != null) {  
    25.                 mCamera.release();  
    26.                 mCamera = null;  
    27.             }  
    28.         }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值