android mediarecord 实现暂停断点录音功能
原文出处:blog.csdn.net/wanli_smile/article/details/7715030
最近研究了下MediaRecorder的录音功能,发现暂停之后,继续录音这个功能,网上参考的资料比较少,现在将自己的学习成果分享大家:
基本原理如下:MediaRecorder通过MIC录音,系统没有自带的pause功能,每次暂停录音,都会结束本次的录音。现在本人的设计思路是:MediaRecorder录音暂停时,保存这段所录下的音频A,继续录音后,再次暂停,保留录音音频B;以此类推直到最终的录音结束时,依次读取之前保存的A、B……的录音文件,并将其合并在一起。涉及的技术:文件的保存读取、音频的合并等
音频的合并:设置MediaRecorder的音频输出格式mMediaRecorder01.setOutputFormat(MediaRecorder.OutputFormat.RAW_AMR);
资源代码:
http://download.csdn.net/detail/wanli_smile/4410240
有图有真相:
public class EX07 extends Activity {
private ImageButton myButton1;
private ImageButton myButton2;
private ImageButton myButton3;
private ImageButton myButton4;
private Button myButton;
private ListView myListView1;
private String strTempFile = "YYT_";
private File myRecAudioFile;
/**录音保存路径**/
private File myRecAudioDir;
private File myPlayFile;
private MediaRecorder mMediaRecorder01;
private int mMinute;
private boolean xx=true;
/**存放音频文件列表**/
private ArrayList recordFiles;
private ArrayAdapter adapter;
private TextView myTextView1;
/**文件存在**/
private boolean sdcardExit;
/**是否停止录音**/
private boolean isStopRecord;
/**按钮背景图片的标志位**/
private boolean sigle = false;
private String length1 = null;
private final String SUFFIX=".amr";
/**暂停按钮**/
Button buttonpause;
/**记录需要合成的几段amr语音文件**/
private ArrayList list;
int second=0;
int minute=0;
/**计时器**/
Timer timer;
/**是否暂停标志位**/
private boolean isPause;
/**在暂停状态中**/
private boolean inThePause;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//暂停标志位 为false
isPause=false;
//暂停状态标志位
inThePause=false;
//初始化list
list=new ArrayList();
//四个按钮
myButton1 = (ImageButton) findViewById(R.id.ImageButton01);
myButton2 = (ImageButton) findViewById(R.id.ImageButton02);
myButton3 = (ImageButton) findViewById(R.id.ImageButton03);
myButton4 = (ImageButton) findViewById(R.id.ImageButton04);
myButton = (Button) findViewById(R.id.myButton);
buttοnpause=(Button)findViewById(R.id.mypuase);
myListView1 = (ListView) findViewById(R.id.ListView01);
myTextView1 = (TextView) findViewById(R.id.TextView01);
myButton2.setEnabled(false);
myButton3.setEnabled(false);
myButton4.setEnabled(false);
myPlayFile=null;
// 判断sd Card是否插入
sdcardExit = Environment.getExternalStorageState().equals(
android.os.Environment.MEDIA_MOUNTED);
// 取得sd card路径作为录音文件的位置
if (sdcardExit){
String pathStr = Environment.getExternalStorageDirectory().getPath()+"/YYT";
myRecAudioDir= new File(pathStr);
if(!myRecAudioDir.exists()){
myRecAudioDir.mkdirs();
Log.v("录音", "创建录音文件!" + myRecAudioDir.exists());
}
// Environment.getExternalStorageDirectory().getPath() + "/" + PREFIX + "/";
}
// 取得sd card 目录里的.arm文件
getRecordFiles();
adapter = new ArrayAdapter(this,
android.R.layout.simple_list_item_1, recordFiles);
// 将ArrayAdater添加ListView对象中
myListView1.setAdapter(adapter);
// 录音
myButton1.setOnClickListener(new ImageButton.OnClickListener() {
@Override
public void onClick(View v) {
second=0;
minute=0;
list.clear();
// Calendar c=Calendar.getInstance();
// int mMinute1=c.get(Calendar.MINUTE);
sigle = true;
// TODO Auto-generated method stub
start();
if (sigle = false) {
myButton1.setBackgroundResource(R.drawable.record_hover1);
} else {
myButton1.setBackgroundResource(R.drawable.record_dis1);
myButton2.setBackgroundResource(R.drawable.stop_hover2);
myButton3.setBackgroundResource(R.drawable.play_hover1);
myButton4.setBackgroundResource(R.drawable.delete_hover);
}
}
});
// 停止
myButton2.setOnClickListener(new ImageButton.OnClickListener() {
@Override
public void onClick(View v) {
xx=false;
sigle = true;
timer.cancel();
// TODO Auto-generated method stub
//这里写暂停处理的 文件!加上list里面 语音合成起来
if(isPause){
//在暂停状态按下结束键,处理list就可以了
if(inThePause){
getInputCollection(list, false);
}
//在正在录音时,处理list里面的和正在录音的语音
else{
list.add(myRecAudioFile.getPath());
recodeStop();
getInputCollection(list, true);
}
//还原标志位
isPause=false;
inThePause=false;
buttonpause.setText("暂停录音");
// adapter.add(myRecAudioFile.getName());
}
//若录音没有经过任何暂停
else{
if (myRecAudioFile != null) {
// 停止录音
mMediaRecorder01.stop();
mMediaRecorder01.release();
mMediaRecorder01 = null;
// 将录音频文件给Adapter
adapter.add(myRecAudioFile.getName());
DecimalFormat df = new DecimalFormat("#.000");
if (myRecAudioFile.length() <= 1024*1024) {
//length1 = (myRecAudioFile.length() / 1024.0)+"";
length1=df.format(myRecAudioFile.length() / 1024.0)+"K";
} else {
//length1 = (myRecAudioFile.length() / 1024.0 / 1024)+"";
//DecimalFormat df = new DecimalFormat("#.000");
length1=df.format(myRecAudioFile.length() / 1024.0 / 1024)+"M";
}
System.out.println(length1);
myTextView1.setText("停 止" + myRecAudioFile.getName()
+ "文件大小为:" + length1);
myButton2.setEnabled(false);
}
}
if (sigle = false) {
myButton2.setBackgroundResource(R.drawable.stop_hover2);
} else {
myButton1.setBackgroundResource(R.drawable.record_hover1);
myButton2.setBackgroundResource(R.drawable.stop1);
myButton3.setBackgroundResource(R.drawable.play_hover1);
myButton4.setBackgroundResource(R.drawable.delete_hover);
}
//停止录音了
isStopRecord = true;
}
});
// 播放
myButton3.setOnClickListener(new ImageButton.OnClickListener() {
@Override
public void onClick(View v) {
sigle = true;
// TODO Auto-generated method stub
if (myPlayFile != null && myPlayFile.exists()) {
// 打开播放程序
openFile(myPlayFile);
} else {
Toast.makeText(EX07.this, "你选的是一个空文件", Toast.LENGTH_LONG)
.show();
Log.d("没有选择文件","没有选择文件");
}
if (sigle = false) {
myButton3.setBackgroundResource(R.drawable.play_hover1);
} else {
myButton1.setBackgroundResource(R.drawable.record_hover1);
myButton2.setBackgroundResource(R.drawable.stop_hover2);
myButton3.setBackgroundResource(R.drawable.play1);
myButton4.setBackgroundResource(R.drawable.delete_hover);
}
}
});
// 删除
myButton4.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
sigle = true;
// TODO Auto-generated method stub
if (myPlayFile != null) {
// 先将Adapter删除文件名
adapter.remove(myPlayFile.getName());
// 删除文件
if (myPlayFile.exists())
myPlayFile.delete();
myTextView1.setText("完成删除!");
}
if (sigle = false) {
myButton4.setBackgroundResource(R.drawable.delete_hover);
} else {
myButton1.setBackgroundResource(R.drawable.record_hover1);
myButton2.setBackgroundResource(R.drawable.stop_hover2);
myButton3.setBackgroundResource(R.drawable.play_hover1);
myButton4.setBackgroundResource(R.drawable.delete_dis);
}
}
});
/**
* 暂停按钮,记录之前保存的语音文件
*/
buttonpause.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
isPause=true;
//已经暂停过了,再次点击按钮 开始录音,录音状态在录音中
if(inThePause){
buttonpause.setText("暂停录音");
start();
inThePause=false;
}
//正在录音,点击暂停,现在录音状态为暂停
else{
//当前正在录音的文件名,全程
list.add(myRecAudioFile.getPath());
inThePause=true;
recodeStop();
//start();
buttonpause.setText("继续录音");
//计时停止
timer.cancel();
}
}
});
myListView1
.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView> arg, View arg1,
int arg2, long arg3) {
// TODO Auto-generated method stub
// 当有单点击文件名时将删除按钮及播放按钮Enable
myButton3.setEnabled(true);
myButton4.setEnabled(true);
myPlayFile = new File(myRecAudioDir.getAbsolutePath()
+ File.separator
+ ((TextView) arg1).getText().toString());
DecimalFormat df = new DecimalFormat("#.000");
if (myPlayFile.length() <= 1024*1024) {
length1=df.format(myPlayFile.length() / 1024.0)+"K";
} else {
length1=df.format(myPlayFile.length() / 1024.0/1024)+"M";
}
myTextView1.setText("你选的是"
+ ((TextView) arg1).getText().toString()
+ "文件大小为:" + length1);
Toast.makeText(EX07.this,"你选的是" + (((TextView) arg1).getText())+ "文件大小为:" + length1,
Toast.LENGTH_LONG).show();
}
});
myButton.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
showSize show = new showSize();
String text = show.showsize();
Toast.makeText(EX07.this, text, Toast.LENGTH_LONG).show();
}
});
}
protected void recodeStop() {
if (mMediaRecorder01 != null && !isStopRecord) {
// 停止录音
mMediaRecorder01.stop();
mMediaRecorder01.release();
mMediaRecorder01 = null;
}
timer.cancel();
}
/**
* activity的生命周期,stop时关闭录音资源
*/
@Override
protected void onStop() {
// TODO Auto-generated method stub
if (mMediaRecorder01 != null && !isStopRecord) {
// 停止录音
mMediaRecorder01.stop();
mMediaRecorder01.release();
mMediaRecorder01 = null;
}
super.onStop();
}
/**
* 获取目录下的所有音频文件
*/
private void getRecordFiles() {
// TODO Auto-generated method stub
recordFiles = new ArrayList();
if (sdcardExit) {
File files[] = myRecAudioDir.listFiles();
if (files != null) {
for (int i = 0; i < files.length; i++) {
if (files[i].getName().indexOf(".") >= 0) { // 只取.amr 文件
String fileS = files[i].getName().substring(
files[i].getName().indexOf("."));
if (fileS.toLowerCase().equals(".mp3")
|| fileS.toLowerCase().equals(".amr")
|| fileS.toLowerCase().equals(".mp4"))
recordFiles.add(files[i].getName());
}
}
}
}
}
// 打开录音播放程序
private void openFile(File f) {
Intent intent = new Intent();
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction(android.content.Intent.ACTION_VIEW);
String type = getMIMEType(f);
intent.setDataAndType(Uri.fromFile(f), type);
startActivity(intent);
// Uri uri=Uri.fromFile(f);
// MediaPlayer mediaPlayer=MediaPlayer.create(this, uri);
// try {
// mediaPlayer.prepare();
// } catch (IllegalStateException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// } catch (IOException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// mediaPlayer.start();
}
private String getMIMEType(File f) {
String end = f.getName().substring(f.getName().lastIndexOf(".") + 1,
f.getName().length()).toLowerCase();
String type = "";
if (end.equals("mp3") || end.equals("aac") || end.equals("amr")
|| end.equals("mpeg") || end.equals("mp4")) {
type = "audio";
} else if (end.equals("jpg") || end.equals("gif") || end.equals("png")
|| end.equals("jpeg")) {
type = "image";
} else {
type = "*";
}
type += "/";
return type;
}
private void start(){
TimerTask timerTask=new TimerTask() {
@Override
public void run() {
// TODO Auto-generated method stub
second++;
if(second>=60){
second=0;
minute++;
}
handler.sendEmptyMessage(1);
}
};
timer=new Timer();
timer.schedule(timerTask, 1000,1000);
try {
if (!sdcardExit) {
Toast.makeText(EX07.this, "请插入SD card",
Toast.LENGTH_LONG).show();
return;
}
String mMinute1=getTime();
Toast.makeText(EX07.this, "当前时间是:"+mMinute1,Toast.LENGTH_LONG).show();
// 创建音频文件
// myRecAudioFile = File.createTempFile(mMinute1, ".amr",
// myRecAudioDir);
myRecAudioFile=new File(myRecAudioDir,mMinute1+SUFFIX);
mMediaRecorder01 = new MediaRecorder();
// 设置录音为麦克风
mMediaRecorder01
.setAudioSource(MediaRecorder.AudioSource.MIC);
mMediaRecorder01
.setOutputFormat(MediaRecorder.OutputFormat.RAW_AMR);
mMediaRecorder01
.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
//录音文件保存这里
mMediaRecorder01.setOutputFile(myRecAudioFile
.getAbsolutePath());
mMediaRecorder01.prepare();
mMediaRecorder01.start();
// mMediaRecorder01.getMaxAmplitude();
// mMediaRecorder01.getAudioSourceMax();
mMediaRecorder01.setOnInfoListener(new OnInfoListener() {
@Override
public void onInfo(MediaRecorder mr, int what, int extra) {
// TODO Auto-generated method stub
int a=mr.getMaxAmplitude();
Toast.makeText(EX07.this, a, 500).show();
}
});
myTextView1.setText("录音中......");
myButton2.setEnabled(true);
myButton3.setEnabled(false);
myButton4.setEnabled(false);
isStopRecord = false;
} catch (IOException e) {
e.printStackTrace();
}
}
private String getTime(){
SimpleDateFormat formatter = new SimpleDateFormat ("yyyy年MM月dd日HH:mm:ss");
Date curDate=new Date(System.currentTimeMillis());//获取当前时间
String time = formatter.format(curDate);
System.out.println("当前时间");
return time;
}
Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
myTextView1.setText("录音时间:"+minute+":"+second);
}
};
/**
* @param isAddLastRecord 是否需要添加list之外的最新录音,一起合并
* @return 将合并的流用字符保存
*/
public void getInputCollection(List list,boolean isAddLastRecord){
String mMinute1=getTime();
Toast.makeText(EX07.this, "当前时间是:"+mMinute1,Toast.LENGTH_LONG).show();
// 创建音频文件,合并的文件放这里
File file1=new File(myRecAudioDir,mMinute1+SUFFIX);
FileOutputStream fileOutputStream = null;
if(!file1.exists()){
try {
file1.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
fileOutputStream=new FileOutputStream(file1);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//list里面为暂停录音 所产生的 几段录音文件的名字,中间几段文件的减去前面的6个字节头文件
for(int i=0;i