Welcome 微信登录
编程资源 图片资源库 蚂蚁家优选 PDF转换器

首页 / 操作系统 / Linux / AndroidMediaRecorder实现暂停断点录音功能

最近研究了下Android  MediaRecorder的录音功能,发现暂停之后,继续录音这个功能,网上参考的资料比较少,现在将自己的学习成果分享大家:基本原理如下:MediaRecorder通过MIC录音,系统没有自带的pause功能,每次暂停录音,都会结束本次的录音。现在本人的设计思路是:MediaRecorder录音暂停时,保存这段所录下的音频A,继续录音后,再次暂停,保留录音音频B;以此类推直到最终的录音结束时,依次读取之前保存的A、B……的录音文件,并将其合并在一起。涉及的技术:文件的保存读取、音频的合并等音频的合并:设置MediaRecorder的音频输出格式mMediaRecorder01.setOutputFormat(MediaRecorder.OutputFormat.RAW_AMR);mMediaRecorder01 .setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);输出的是amr格式。amr的音频文件的文件头,相对来说是固定的6个字节的固定字符,A.amr文件和B.amr文件的合并,只需将B以字节流读取,去掉前6个字节,和A的字节流合并后保存,就实现了音频合并,不涉及复杂的音频编码问题。(MediaRecorder的音频输出格式比较多,有jpgg、MP3等之类的格式,合成的原理大同小异,只需要注意他们的音频文件头的格式就可以了。)资源代码:免费下载地址在 http://linux.linuxidc.com/用户名与密码都是www.linuxidc.com具体下载目录在 /2012年资料/7月/4日/Android  MediaRecorder实现暂停断点录音功能有图有真相: 
  1. public class EX07 extends Activity {  
  2.     private ImageButton myButton1;  
  3.     private ImageButton myButton2;  
  4.     private ImageButton myButton3;  
  5.     private ImageButton myButton4;  
  6.     private Button myButton;  
  7.     private ListView myListView1;  
  8.     private String strTempFile = "YYT_";  
  9.     private File myRecAudioFile;  
  10.     /**录音保存路径**/  
  11.     private File myRecAudioDir;  
  12.     private File myPlayFile;  
  13.     private MediaRecorder mMediaRecorder01;  
  14.     private int mMinute;  
  15.     private boolean xx=true;  
  16.     /**存放音频文件列表**/  
  17.     private ArrayList<String> recordFiles;  
  18.     private ArrayAdapter<String> adapter;  
  19.     private TextView myTextView1;  
  20.     /**文件存在**/  
  21.     private boolean sdcardExit;  
  22.     /**是否停止录音**/  
  23.     private boolean isStopRecord;  
  24.     /**按钮背景图片的标志位**/  
  25.     private boolean sigle = false;  
  26.     private String length1 = null;  
  27.       
  28.     private  final String SUFFIX=".amr";  
  29.       
  30.       
  31.     /**暂停按钮**/  
  32.     Button buttonpause;  
  33.       
  34.       
  35.     /**记录需要合成的几段amr语音文件**/  
  36.     private ArrayList<String> list;  
  37.       
  38.       
  39.     int second=0;  
  40.       
  41.     int minute=0;  
  42.       
  43.     /**计时器**/  
  44.     Timer timer;  
  45.       
  46.       
  47.     /**是否暂停标志位**/  
  48.     private boolean isPause;  
  49.       
  50.     /**在暂停状态中**/  
  51.     private boolean inThePause;  
  52.       
  53.   
  54.     /** Called when the activity is first created. */  
  55.     @Override  
  56.     public void onCreate(Bundle savedInstanceState) {  
  57.           
  58.         super.onCreate(savedInstanceState);  
  59.         setContentView(R.layout.main);  
  60.           
  61.         //暂停标志位 为false   
  62.         isPause=false;  
  63.         //暂停状态标志位   
  64.         inThePause=false;  
  65.           
  66.         //初始化list   
  67.         list=new ArrayList<String>();  
  68.           
  69.         //四个按钮   
  70.         myButton1 = (ImageButton) findViewById(R.id.ImageButton01);  
  71.         myButton2 = (ImageButton) findViewById(R.id.ImageButton02);  
  72.         myButton3 = (ImageButton) findViewById(R.id.ImageButton03);  
  73.         myButton4 = (ImageButton) findViewById(R.id.ImageButton04);  
  74.         myButton = (Button) findViewById(R.id.myButton);  
  75.         buttonpause=(Button)findViewById(R.id.mypuase);  
  76.         myListView1 = (ListView) findViewById(R.id.ListView01);  
  77.         myTextView1 = (TextView) findViewById(R.id.TextView01);  
  78.         myButton2.setEnabled(false);  
  79.         myButton3.setEnabled(false);  
  80.         myButton4.setEnabled(false);  
  81.           
  82.         myPlayFile=null;  
  83.   
  84.         // 判断sd Card是否插入   
  85.         sdcardExit = Environment.getExternalStorageState().equals(  
  86.                 android.os.Environment.MEDIA_MOUNTED);  
  87.         // 取得sd card路径作为录音文件的位置   
  88.         if (sdcardExit){  
  89.             String pathStr = Environment.getExternalStorageDirectory().getPath()+"/YYT";  
  90.             myRecAudioDir= new File(pathStr);  
  91.             if(!myRecAudioDir.exists()){  
  92.                 myRecAudioDir.mkdirs();  
  93.                 Log.v("录音""创建录音文件!" + myRecAudioDir.exists());  
  94.             }  
  95. //          Environment.getExternalStorageDirectory().getPath() + "/" + PREFIX + "/";   
  96.         }  
  97.         // 取得sd card 目录里的.arm文件   
  98.         getRecordFiles();  
  99.           
  100.         adapter = new ArrayAdapter<String>(this,  
  101.                 android.R.layout.simple_list_item_1, recordFiles);  
  102.         // 将ArrayAdater添加ListView对象中   
  103.         myListView1.setAdapter(adapter);  
  104.         // 录音   
  105.       
  106.         myButton1.setOnClickListener(new ImageButton.OnClickListener() {  
  107.        
  108.             @Override  
  109.             public void onClick(View v) {  
  110.             second=0;  
  111.             minute=0;  
  112.                   
  113.             list.clear();  
  114. //          Calendar c=Calendar.getInstance();   
  115. //          int mMinute1=c.get(Calendar.MINUTE);   
  116.               
  117.                 sigle = true;  
  118.                 // TODO Auto-generated method stub   
  119.   
  120.                  start();  
  121.   
  122.                 if (sigle = false) {  
  123.                     myButton1.setBackgroundResource(R.drawable.record_hover1);  
  124.                 } else {  
  125.                     myButton1.setBackgroundResource(R.drawable.record_dis1);  
  126.                     myButton2.setBackgroundResource(R.drawable.stop_hover2);  
  127.                     myButton3.setBackgroundResource(R.drawable.play_hover1);  
  128.                     myButton4.setBackgroundResource(R.drawable.delete_hover);  
  129.                 }  
  130.               
  131.               
  132.             }  
  133.   
  134.         });  
  135.         // 停止   
  136.         myButton2.setOnClickListener(new ImageButton.OnClickListener() {  
  137.   
  138.             @Override  
  139.             public void onClick(View v) {  
  140.                   
  141.                   
  142.                 xx=false;  
  143.                 sigle = true;  
  144.                 timer.cancel();  
  145.                 // TODO Auto-generated method stub   
  146.                   
  147.                   
  148.                 //这里写暂停处理的 文件!加上list里面 语音合成起来   
  149.                 if(isPause){  
  150.                       
  151.                     //在暂停状态按下结束键,处理list就可以了   
  152.                     if(inThePause){  
  153.                         getInputCollection(list, false);  
  154.                     }  
  155.                     //在正在录音时,处理list里面的和正在录音的语音   
  156.                     else{  
  157.                         list.add(myRecAudioFile.getPath());  
  158.                         recodeStop();  
  159.                         getInputCollection(list, true);  
  160.                     }  
  161.                       
  162.                     //还原标志位   
  163.                     isPause=false;  
  164.                     inThePause=false;  
  165.                     buttonpause.setText("暂停录音");  
  166.                       
  167.                   
  168.                       
  169.                       
  170.                 //  adapter.add(myRecAudioFile.getName());   
  171.                       
  172.                 }  
  173.                   
  174.                   
  175.                   
  176.                 //若录音没有经过任何暂停   
  177.                 else{  
  178.                       
  179.                   
  180.                     if (myRecAudioFile != null) {  
  181.                     // 停止录音   
  182.                     mMediaRecorder01.stop();  
  183.                     mMediaRecorder01.release();  
  184.                     mMediaRecorder01 = null;  
  185.                     // 将录音频文件给Adapter   
  186.                     adapter.add(myRecAudioFile.getName());  
  187.                     DecimalFormat df = new DecimalFormat("#.000");  
  188.                     if (myRecAudioFile.length() <= 1024*1024) {  
  189.                         //length1 = (myRecAudioFile.length() / 1024.0)+"";   
  190.                           
  191.                           length1=df.format(myRecAudioFile.length() / 1024.0)+"K";  
  192.                     } else {  
  193.                         //length1 = (myRecAudioFile.length() / 1024.0 / 1024)+"";   
  194.                         //DecimalFormat df = new DecimalFormat("#.000");   
  195.                           length1=df.format(myRecAudioFile.length() / 1024.0 / 1024)+"M";  
  196.                     }  
  197.                         System.out.println(length1);  
  198.                         
  199.                       myTextView1.setText("停  止" + myRecAudioFile.getName()  
  200.                             + "文件大小为:" + length1);  
  201.                     myButton2.setEnabled(false);  
  202.               
  203.                 }  
  204.                   
  205.             }  
  206.   
  207.                 if (sigle = false) {  
  208.                     myButton2.setBackgroundResource(R.drawable.stop_hover2);  
  209.                 } else {  
  210.                     myButton1.setBackgroundResource(R.drawable.record_hover1);  
  211.                     myButton2.setBackgroundResource(R.drawable.stop1);  
  212.                     myButton3.setBackgroundResource(R.drawable.play_hover1);  
  213.                     myButton4.setBackgroundResource(R.drawable.delete_hover);  
  214.                 }  
  215.                   
  216.                 //停止录音了   
  217.                 isStopRecord = true;  
  218.             }  
  219.   
  220.         });  
  221.   
  222.         // 播放   
  223.         myButton3.setOnClickListener(new ImageButton.OnClickListener() {  
  224.   
  225.             @Override  
  226.             public void onClick(View v) {  
  227.                 sigle = true;  
  228.                 // TODO Auto-generated method stub   
  229.                 if (myPlayFile != null && myPlayFile.exists()) {  
  230.                     // 打开播放程序   
  231.                     openFile(myPlayFile);  
  232.                 } else {  
  233.                     Toast.makeText(EX07.this"你选的是一个空文件", Toast.LENGTH_LONG)  
  234.                             .show();  
  235.                     Log.d("没有选择文件","没有选择文件");  
  236.                 }  
  237.                 if (sigle = false) {  
  238.                     myButton3.setBackgroundResource(R.drawable.play_hover1);  
  239.                 } else {  
  240.                     myButton1.setBackgroundResource(R.drawable.record_hover1);  
  241.                     myButton2.setBackgroundResource(R.drawable.stop_hover2);  
  242.                     myButton3.setBackgroundResource(R.drawable.play1);  
  243.                     myButton4.setBackgroundResource(R.drawable.delete_hover);  
  244.                 }  
  245.             }  
  246.   
  247.         });  
  248.   
  249.         // 删除   
  250.         myButton4.setOnClickListener(new OnClickListener() {  
  251.   
  252.             @Override  
  253.             public void onClick(View v) {  
  254.                 sigle = true;  
  255.                 // TODO Auto-generated method stub   
  256.   
  257.                 if (myPlayFile != null) {  
  258.                     // 先将Adapter删除文件名   
  259.                     adapter.remove(myPlayFile.getName());  
  260.                     // 删除文件   
  261.                     if (myPlayFile.exists())  
  262.                         myPlayFile.delete();  
  263.                     myTextView1.setText("完成删除!");  
  264.   
  265.                 }  
  266.                 if (sigle = false) {  
  267.                     myButton4.setBackgroundResource(R.drawable.delete_hover);  
  268.                 } else {  
  269.                     myButton1.setBackgroundResource(R.drawable.record_hover1);  
  270.                     myButton2.setBackgroundResource(R.drawable.stop_hover2);  
  271.                     myButton3.setBackgroundResource(R.drawable.play_hover1);  
  272.                     myButton4.setBackgroundResource(R.drawable.delete_dis);  
  273.                 }  
  274.             }  
  275.         });  
  276.           
  277.         /** 
  278.          * 暂停按钮,记录之前保存的语音文件 
  279.          */  
  280.         buttonpause.setOnClickListener(new OnClickListener() {  
  281.               
  282.             @Override  
  283.             public void onClick(View v) {  
  284.                 // TODO Auto-generated method stub   
  285.                   
  286.             isPause=true;  
  287.                   
  288.                 //已经暂停过了,再次点击按钮 开始录音,录音状态在录音中   
  289.             if(inThePause){  
  290.                 buttonpause.setText("暂停录音");  
  291.                 start();  
  292.                 inThePause=false;  
  293.                   
  294.                   
  295.             }  
  296.             //正在录音,点击暂停,现在录音状态为暂停   
  297.             else{  
  298.                   
  299.                 //当前正在录音的文件名,全程   
  300.                 list.add(myRecAudioFile.getPath());  
  301.                 inThePause=true;  
  302.                 recodeStop();  
  303.                 //start();   
  304.                 buttonpause.setText("继续录音");  
  305.                   
  306.                 //计时停止   
  307.                 timer.cancel();  
  308.             }  
  309.             }  
  310.         });  
  311.           
  312.           
  313.         myListView1  
  314.                 .setOnItemClickListener(new AdapterView.OnItemClickListener() {  
  315.                     @Override  
  316.                     public void onItemClick(AdapterView<?> arg, View arg1,  
  317.                             int arg2, long arg3) {  
  318.                         // TODO Auto-generated method stub   
  319.                         // 当有单点击文件名时将删除按钮及播放按钮Enable   
  320.                         myButton3.setEnabled(true);  
  321.                         myButton4.setEnabled(true);  
  322.                         myPlayFile = new File(myRecAudioDir.getAbsolutePath()  
  323.                                 + File.separator  
  324.                                 + ((TextView) arg1).getText().toString());  
  325.                           
  326.                         DecimalFormat df = new DecimalFormat("#.000");  
  327.                         if (myPlayFile.length() <= 1024*1024) {  
  328.                             length1=df.format(myPlayFile.length() / 1024.0)+"K";  
  329.                         } else {  
  330.                             length1=df.format(myPlayFile.length() / 1024.0/1024)+"M";  
  331.                         }  
  332.                         myTextView1.setText("你选的是"  
  333.                                 + ((TextView) arg1).getText().toString()  
  334.                                 + "文件大小为:" + length1);  
  335.                         Toast.makeText(EX07.this,"你选的是" + (((TextView) arg1).getText())+ "文件大小为:" + length1,  
  336.                                         Toast.LENGTH_LONG).show();  
  337.   
  338.                     }  
  339.   
  340.                 });  
  341.   
  342.         myButton.setOnClickListener(new Button.OnClickListener() {  
  343.   
  344.             @Override  
  345.             public void onClick(View v) {  
  346.                 // TODO Auto-generated method stub   
  347.                 showSize show = new showSize();  
  348.                 String text = show.showsize();  
  349.                 Toast.makeText(EX07.this, text, Toast.LENGTH_LONG).show();  
  350.             }  
  351.         });  
  352.     }  
  353.   
  354.       
  355.     protected void recodeStop() {  
  356.         if (mMediaRecorder01 != null && !isStopRecord) {  
  357.             // 停止录音   
  358.             mMediaRecorder01.stop();  
  359.             mMediaRecorder01.release();  
  360.             mMediaRecorder01 = null;  
  361.         }  
  362.           
  363.         timer.cancel();  
  364.     }  
  365.       
  366.   
  367.     /** 
  368.      * activity的生命周期,stop时关闭录音资源 
  369.      */  
  370.     @Override  
  371.     protected void onStop() {  
  372.         // TODO Auto-generated method stub   
  373.         if (mMediaRecorder01 != null && !isStopRecord) {  
  374.             // 停止录音   
  375.             mMediaRecorder01.stop();  
  376.             mMediaRecorder01.release();  
  377.             mMediaRecorder01 = null;  
  378.         }  
  379.         super.onStop();  
  380.     }  
  381.   
  382.   
  383.     /** 
  384.      * 获取目录下的所有音频文件 
  385.      */  
  386.     private void getRecordFiles() {  
  387.         // TODO Auto-generated method stub   
  388.         recordFiles = new ArrayList<String>();  
  389.         if (sdcardExit) {  
  390.             File files[] = myRecAudioDir.listFiles();  
  391.             if (files != null) {  
  392.                 for (int i = 0; i < files.length; i++) {  
  393.                     if (files[i].getName().indexOf(".") >= 0) { // 只取.amr 文件   
  394.                         String fileS = files[i].getName().substring(  
  395.                                 files[i].getName().indexOf("."));  
  396.                         if (fileS.toLowerCase().equals(".mp3")  
  397.        &