本鑒于現(xiàn)在大部分的手機(jī)都提供了音頻錄制的功能,Android系統(tǒng)相應(yīng)地提供了對(duì)音頻及視頻錄制的支持,當(dāng)然這也需要有硬件的支持。要想錄制音頻及視頻需要通過(guò)MediaRecorder來(lái)完成。
MediaRecorder類(lèi)位于android.media包中,它包含了音頻及視頻的記錄功能。常用的方法如表1所示。
表1 MediaRecorder的常用方法
方法 |
描述 |
方法 |
描述 |
start() |
開(kāi)始錄制 |
prepare() |
準(zhǔn)備錄制 |
pause() |
暫停錄制 |
reset() |
重新開(kāi)始 |
stop() |
停止錄制 |
release() |
釋放資源 |
MediaRecorder類(lèi)的工作流程如圖1所示。

要實(shí)現(xiàn)音頻及視頻的錄制的步驟說(shuō)明如下所示。
在工程的res/drawable目錄下放置兩個(gè)圖片文件,用來(lái)設(shè)置控制按鈕的圖片。
□ 在布局文件main.xml中添加3個(gè)View組件,其中TextView用來(lái)顯示標(biāo)題,其余兩個(gè)按鈕用來(lái)控制開(kāi)始錄制和停止錄制。
□ 創(chuàng)建Activity類(lèi)MainActivity。
□ 生成兩個(gè)ImageButton實(shí)例。
□ 創(chuàng)建loadCip()方法,實(shí)例化MediaRecorder。
□ 在onCreate()方法中實(shí)例化。
□ 創(chuàng)建record()方法,調(diào)用MediaRecorder的start()方法錄制,同時(shí)使錄制按鈕失效,使停止按鈕生效。
□ 創(chuàng)建stop()方法,調(diào)用MediaRecorder的stop()方法停止錄制。
□ 創(chuàng)建error()方法捕獲異常。
□ 創(chuàng)建setProperty()方法,設(shè)置MediaRecorder的屬性,包括用MediaRecorder.setAudio
Source()方法來(lái)設(shè)置音頻源,你可以用MediaRecorder.AudioSource.MIC方法來(lái)設(shè)置麥克風(fēng);用MediaRecorder.setOutputFormat()方法來(lái)設(shè)置輸出文件格式;用MediaRecorder.setAudioEncoder()方法來(lái)設(shè)置音頻編碼格式。
□ 創(chuàng)建setup()方法,調(diào)用loadClip(),使錄制按鈕生效,使停止按鈕失效。
□ 為錄制按鈕添加單擊事件,調(diào)用play()方法錄制。
□ 為停止按鈕添加單擊事件,調(diào)用stop()方法停止錄制。
□ 當(dāng)實(shí)現(xiàn)的MediaRecorder類(lèi)完成音頻的捕捉后,調(diào)用release()方法。
布局文件main.xml的代碼如代碼清單1所示。
代碼清單1 main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="迷你錄音器"
/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ImageButton
android:id="@+id/record"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/record"
></ImageButton>
<ImageButton
android:id="@+id/stop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/stop"
></ImageButton>
</LinearLayout>
</LinearLayout>
Activity代碼如代碼清單2所示。
代碼清單2 MainActivity.java
package cn.com.farsight.record;
import java.io.File;
import java.io.IOException;
import com.examples.android.helloactivity.R;
import android.app.Activity;
import android.app.AlertDialog;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageButton;
public class MainActivity extends Activity {
//聲明圖片按鈕ImageButton
private ImageButton record,stop;
//聲明MediaRecorder
private MediaRecorder mr;
//聲明路徑
private String path;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//設(shè)置當(dāng)前Activity界面布局
setContentView(R.layout.main);
//通過(guò)findViewById方法獲得ImageButton實(shí)例
record = (ImageButton)findViewById(R.id.record);
stop = (ImageButton)findViewById(R.id.stop);
//為錄制按鈕設(shè)置單擊事件監(jiān)聽(tīng)器
record.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
//錄制
record();
}
});
//為停止按鈕設(shè)置單擊事件監(jiān)聽(tīng)器
stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
//停止錄制
stop();
}
});
//準(zhǔn)備
setup();
}
//設(shè)置路徑
private void setPath() throws IOException{
//路徑為sd擴(kuò)展卡
path = "/sdcard/test.mp3";
//獲得sd擴(kuò)展卡狀態(tài)
String state = android.os.Environment.getExternalStorageState();
//判斷是否安裝擴(kuò)展卡
if(!state.equals(android.os.Environment.MEDIA_MOUNTED)){
throw new IOException("SD沒(méi)有安裝,它的狀態(tài)是"+state+".");
}
//獲取文件父目錄
File directory = new File(path).getParentFile();
if(!directory.exists()&& !directory.mkdirs()){
throw new IOException("文件不能被創(chuàng)建. ");
}
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
if(stop.isEnabled()){
//停止錄制
stop();
}
}
//錄制方法
private void record(){
try{
//準(zhǔn)備
mr.prepare();
}catch(IllegalStateException e){
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
//開(kāi)始錄制
mr.start();
//使錄制按鈕失效
record.setEnabled(false);
//使停止按鈕生效
stop.setEnabled(true);
}
//停止
private void stop(){
//停止錄制
mr.stop();
//使停止按鈕失效
stop.setEnabled(false);
//使錄制按鈕生效
record.setEnabled(true);
//釋放資源
mr.release();
}
//設(shè)置屬性
private void setProperty(){
try{
//實(shí)例化MediaRecorder
mr = new MediaRecorder();
//設(shè)置音頻源
mr.setAudioSource(MediaRecorder.AudioSource.MIC);
//設(shè)置輸出格式
mr.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
//設(shè)置音頻編碼器
mr.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
try{
//設(shè)置路徑
setPath();
}catch(IOException e){
e.printStackTrace();
}
//設(shè)置輸出文件
mr.setOutputFile(path);
}catch(Throwable t){
error(t);
}
}
//準(zhǔn)備
private void setup(){
//設(shè)置屬性
setPeoperty();
//使錄制按鈕生效
record.setEnabled(true);
//使停止按鈕生效
stop.setEnabled(false);
}
//錯(cuò)誤提示
private void error(Throwable t){
//對(duì)話(huà)框
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("報(bào)錯(cuò)啦!").setMessage(t.toString()).setPositiveButton("確定", null).show();
}
}