下面是使用MediaRecorder类的定制音频捕获和播放示例的完整代码。
1 package com.nthm.androidtestActivity; 2 3 import java.io.File; 4 import java.io.IOException; 5 import com.nthm.androidtest.R; 6 import android.app.Activity; 7 import android.media.MediaPlayer; 8 import android.media.MediaPlayer.OnCompletionListener; 9 import android.media.MediaRecorder; 10 import android.os.Bundle; 11 import android.os.Environment; 12 import android.view.View; 13 import android.view.View.OnClickListener; 14 import android.widget.Button; 15 import android.widget.TextView;
CustomRecorder活动实现了OnClickListener,从而它可以在用户按下按钮时得到通知;同时实现了OnCompletionListener,从而它可以在MediaPlayer已完成播放音频时响应。
1 public class CustomRecorder extends Activity implements OnClickListener, 2 OnCompletionListener {
该活动会有一系列的用户界面组件。首先是一个称为statusTextView的TextView,其将应用程序的状态报告给用户:“Recording(录制中)”、“Ready to Play(准备播放)”等。
1 private TextView statusTextView;
一系列按钮将用于控制各个方面,这些按钮的名称描述了他们的用途。
1 private Button startRecording; 2 private Button stopRecording; 3 private Button playRecording; 4 private Button finishButton;
同时,还会有一个MediaRecorder用于录制音频,以及一个MediaPlayer用于播放音频。
1 private MediaRecorder recorder; 2 private MediaPlayer player;
最后,有一个audioFile的File对象,它将引用录制到其中的文件。
1 private File audioFile; 2 @Override 3 protected void onCreate(Bundle savedInstanceState) { 4 super.onCreate(savedInstanceState); 5 setContentView(R.layout.customrecorder);
当启动活动时,将把statusTextView设置为“Ready”(准备好)。
1 statusTextView=(TextView) findViewById(R.id.StatusTextView); 2 statusTextView.setText("Ready"); 3 4 stopRecording=(Button) findViewById(R.id.StopRecording); 5 startRecording=(Button) findViewById(R.id.StartRecording); 6 playRecording=(Button) findViewById(R.id.PlayRecording); 7 finishButton=(Button) findViewById(R.id.FinishButton);
将所有的按钮的OnClickListener都设置为this,从而单击他们中的任何一个时都会调用onClick方法。
1 stopRecording.setOnClickListener(this); 2 startRecording.setOnClickListener(this); 3 playRecording.setOnClickListener(this); 4 finishButton.setOnClickListener(this);
最后,在onCreate方法中将禁用stopRecording和playRecording按钮,因为直到启动录制或完成录制时他们才会工作。
1 stopRecording.setEnabled(false); 2 playRecording.setEnabled(false); 3 }
在下面的onClick方法中将处理所有的按钮单击事件。
1 @Override 2 public void onClick(View v) { 3 if(v==finishButton){
如果单击finishButton,那么结束活动。
1 finish(); 2 }else if(v==stopRecording){
如果单击stopRecording按钮,那么停止录制并释放MediaRecorder对象。
1 recorder.stop(); 2 recorder.release();
然后构造一个MediaPlayer对象,并使它准备好播放刚刚录制的音频文件。
1 player=new MediaPlayer(); 2 player.setOnCompletionListener(this);
我们将在MediaPlayer上使用的以下两个方法setDataSource和prepare可能会抛出各种异常。在下面的代码中只是抛出了异常。在你的应用程序开发中,你可能会希望更细致的捕获和处理这些异常,例如当文件不存在是向用户报警。
1 try { 2 player.setDataSource(audioFile.getAbsolutePath()); 3 } catch (IllegalArgumentException e) { 4 e.printStackTrace(); 5 } catch (SecurityException e) { 6 e.printStackTrace(); 7 } catch (IllegalStateException e) { 8 e.printStackTrace(); 9 } catch (IOException e) { 10 e.printStackTrace(); 11 } 12 try { 13 player.prepare(); 14 } catch (IllegalStateException e) { 15 e.printStackTrace(); 16 } catch (IOException e) { 17 e.printStackTrace(); 18 }
设置statusTextView以提醒用户已准备好播放音频文件。
1 statusTextView.setText("Ready to Play");
然后启用playRecording和startRecording按钮,同时禁用stopRecording按钮,因为目前尚没有录制音频。
1 playRecording.setEnabled(true); 2 stopRecording.setEnabled(false); 3 startRecording.setEnabled(true); 4 }else if(v==startRecording){
当按下startRecording按钮时,将构造一个新的MediaRecorder,并调用setAudioSource,setOutputFormat和setAudioEncoder方法。
1 recorder=new MediaRecorder(); 2 recorder.setAudioSource(MediaRecorder.AudioSource.MIC); 3 recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); 4 recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
然后在SD卡上创建一个新的File对象,并调用MediaRecorder对象上的setOutputFile方法。
1 File path=new File(Environment.getExternalStorageDirectory()+"/ceshi"); 2 path.mkdirs(); 3 try { 4 audioFile=File.createTempFile("recording", ".3gp", path); 5 } catch (IOException e) { 6 e.printStackTrace(); 7 } 8 recorder.setOutputFile(audioFile.getAbsolutePath());
调用MediaRecorder上的prepare方法,并开始录制。
1 try { 2 recorder.prepare(); 3 } catch (IllegalStateException e) { 4 e.printStackTrace(); 5 } catch (IOException e) { 6 e.printStackTrace(); 7 } 8 recorder.start();
最后更新statusTextView,并且更改哪些按钮会被启用或禁用。
1 statusTextView.setText("Recording"); 2 3 playRecording.setEnabled(false); 4 stopRecording.setEnabled(true); 5 startRecording.setEnabled(false); 6 }else if(v==playRecording){
最后需要响应的是playRecording。当按下stopRecording按钮时,将构造和配置MediaPlayer对象player。当单击playRecording时,唯一需要做的是开始播放,设置状态消息,并且更改哪些按钮会被启用。
1 player.start(); 2 statusTextView.setText("Playing"); 3 4 playRecording.setEnabled(false); 5 stopRecording.setEnabled(false); 6 startRecording.setEnabled(false); 7 } 8 }
当MediaPlayer对象完成播放一条录音时将调用onCompletion方法。使用该方法来更改状态消息,并设置哪些按钮会被启用。
1 @Override 2 public void onCompletion(MediaPlayer mp) { 3 statusTextView.setText("Ready"); 4 5 playRecording.setEnabled(true); 6 stopRecording.setEnabled(false); 7 startRecording.setEnabled(true); 8 } 9 }
下面是用于上述活动的布局XML文件customrecorder.xml
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 android:layout_width="match_parent" 3 android:layout_height="match_parent" 4 android:orientation="vertical" 5 > 6 <TextView 7 android:id="@+id/StatusTextView" 8 android:text="Status" 9 android:layout_width="fill_parent" 10 android:layout_height="wrap_content" 11 android:textSize="35dip"></TextView> 12 <Button 13 android:layout_width="wrap_content" 14 android:layout_height="wrap_content" 15 android:id="@+id/StartRecording" 16 android:text="Start Recording"/> 17 <Button 18 android:layout_width="wrap_content" 19 android:layout_height="wrap_content" 20 android:id="@+id/StopRecording" 21 android:text="Stop Recording"/> 22 <Button 23 android:layout_width="wrap_content" 24 android:layout_height="wrap_content" 25 android:id="@+id/PlayRecording" 26 android:text="Play Recording"/> 27 <Button 28 android:layout_width="wrap_content" 29 android:layout_height="wrap_content" 30 android:id="@+id/FinishButton" 31 android:text="Finish"/> 32 </LinearLayout>
同时,还需要将以下权限添加到AndroidManifest.xml文件。
1 <uses-permission android:name="android.permission.RECORD_AUDIO"/> 2 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
正如我们看到的那样,使用MediaRecorder开发一个定制的音频捕获程序不是太麻烦。接下来查看一下如何使用MediaRecorder的其他方法来添加其他功能。