用什么类来实现录音

控制OPhone手机运行录音功能,需要创建MediaRecorder对象与存储空间作为录音暂存储之用。本文的示例中有四个按钮,分别是“录音”、“停止”、“播放”、“删除”。如图1所示。
 

arecord命令的录音音量 record 录音_null


图1:录音机的界面

MediaRecorder的生命周期

  • MediaRecorder可以用来录制音频或视频。它具有以下几个状态:
  • Initial:初始状态,在设定视频源或者音频源之后将转换为Initialized状态。
  • Initialized:已初始化状态,可以通过设置输出格式转换为DataSourceConfigured状态,或者通过重新启动转换成Initial状态。
  • DataSourceConfigured:数据源配置状态,这期间可以设定编码方式、输出文件、屏幕旋转、预览显示等等。它仍然可以通过从新启动回到Initial状态,或者通过就绪到达Prepared状态。
  • Prepared:就绪状态,在就绪状态仍然可以通过重新启动方法回到Initialized状态。或者通过start方法进入录制状态。
  • Recording:录制状态,真正在录音的那个状态,前边做的一切都是铺垫,它可以通过停止或者重新启动回到Initial状态。
  • Released:释放状态(官方文档给出的词叫做 Idle state 空闲状态,而官方的图却不这么写),Initial状态可以通过调用释放方法来进入这个状态,这时将会释放所有和MediaRecorder对象绑定的资源。
  • Error:错误状态,当错误发生的时候进入这个状态,它可以通过从新启动进入Initial状态。

其生命周期状态转换关系如图2所示。
 

arecord命令的录音音量 record 录音_null_02


图2:MediaRecorder的生命周期

MediaRecorder如何使用

通常使用MediaRecorder进行声音录制需要遵从以下几个步骤:
 

实例化MediaRecorder类对象:
MediaRecorder iMediaRecorder= new MediaRecorder();
 

  • 设置录音来源 :

              iMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
 

  • 设置输出格式:

            iMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
 

  • 设置编码方式

          iMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
 

  • 设置输出文件

         iMediaRecorder.setOutputFile(PATH_NAME);
 

  • 让MediaRecorder对象处于就绪状态

         iMediaRecorder.prepare();
 

  • 开始录音

        iMediaRecorder.start();
 

  • 停止录音,一旦停止则必须从新配置MediaRecorder对象才能再次开始录音。

        iMediaRecorder.stop();
 

  • 从新启动MediaRecorder对象让它处于空闲状态。

        iMediaRecorder.reset();
 

  • 释放和MediaRecorder对向相关的所有资源。

       iMediaRecorder.release();
 

程序如何实现

OPhone华丽的界面,灵活的界面组合方式给我们开发者带来了极大的便利。
首先来看看我们这个类的成员变量和初始化方法。成员变量一共包含四个ImageButton用来和用户进行交互,之所以用ImageButton是因为它可以把图片显示在按钮上,让程序看起来更加美观。一个ListView用来显示已经录制好的声音片段供用户选择。一个TextView用来告知用户当前程序状态。程序运行之初,将录音按钮以外的按钮设定成不可用状态。
package com.ophone.iRecorder;

//这里为了节省篇幅,忽略了import项


    1. public class ActivityMain extends
    2. private
    3. private
    4. private
    5. private
    6. private
    7. private String iTempFileNameString = "iRecorder_";   
    8. private
    9. private
    10. private
    11. private
    12.   
    13. private
    14. private
    15. private
    16. private boolean
    17. private boolean
    18.   
    19. /** Called when the activity is first created. */
    20. @Override
    21. public void
    22. super.onCreate(savedInstanceState);   
    23.         setContentView(R.layout.main);   
    24.   
    25.         iRecordButton = (ImageButton) findViewById(R.id.ImageButton01);   
    26.         iStopButton = (ImageButton) findViewById(R.id.ImageButton02);   
    27.         iPlayButton = (ImageButton) findViewById(R.id.ImageButton03);   
    28.         iDeleteButton = (ImageButton) findViewById(R.id.ImageButton04);   
    29.         iListView = (ListView) findViewById(R.id.ListView01);   
    30.         iTextView = (TextView) findViewById(R.id.TextView01);   
    31. /* 初始后三个按钮不可用 */
    32. false);   
    33. false);   
    34. false);

       
    需要判断SD卡是否是插入状态,以保证我们可以长时间的进行录音。如果存在则取得SD卡路径作为录音的文件位置。然后取得SD卡中的.amr文件。getRecordFiles()是一个自定义的方法,后面将会有说明。

    1. isSDCardExit = Environment.getExternalStorageState().equals(   
    2.                 android.os.Environment.MEDIA_MOUNTED);   
    3. if
    4.             iRecAudioDir = Environment.getExternalStorageDirectory();   
    5. this.getRecordFiles();      
    6. new ArrayAdapter<String>(this, R.layout.my_simple_list_item,   
    7.                 iRecordFiles);   
    8. /* 将ArrayAdapter添加ListView对象中 */
    9.         iListView.setAdapter(iAdapter);

    对第一个录音按钮我们最需要注意的是在iMediaRecorder.start()之前我们必须调用iMediaRecorder.prepare()来捕获和编码数据,而且prepare()必须要在设置音频源、编码器、以及文件格式之后才能调用!


    1. iRecordButton.setOnClickListener(new
    2. @Override
    3. public void
    4. try
    5. if
    6. this, "请插入SD Card",   
    7.                         Toast.LENGTH_LONG).show();   
    8. return;   
    9.             }   
    10. /* 创建录音文件 */
    11.             iRecAudioFile = File.createTempFile(iTempFileNameString,   
    12. ".amr", iRecAudioDir);   
    13. new
    14. /* 设置录音来源为MIC */
    15.             iMediaRecorder   
    16.                     .setAudioSource(MediaRecorder.AudioSource.MIC);   
    17.             iMediaRecorder   
    18.                     .setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);   
    19.             iMediaRecorder   
    20.                     .setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);   
    21.             iMediaRecorder.setOutputFile(iRecAudioFile   
    22.                     .getAbsolutePath());   
    23.             iMediaRecorder.prepare();   
    24.             iMediaRecorder.start();   
    25. "正在录音");   
    26. true);   
    27. false);   
    28. false);   
    29. false;   
    30. catch
    31. // TODO Auto-generated catch block 
    32.             e.printStackTrace();   
    33.         }   
    34.     }   
    35. });

    在停止录音的时候需要iMediaRecorder.stop()停止录音,一旦停止录音,必须从新配置MediaRecorder才可以。iMediaRecorder.release()用来释放和iMediaRecorder对象相关的所有资源。最后把iMediaRecorder赋值为null。


    1. iStopButton.setOnClickListener(new
    2. @Override
    3. public void
    4. // TODO Auto-generated method stub 
    5. if (iRecAudioFile != null) {   
    6. /* 停止录音 */
    7.               iMediaRecorder.stop();   
    8.               iMediaRecorder.release();   
    9. null;   
    10. /* 将录音频文件名给Adapter */
    11.               iAdapter.add(iRecAudioFile.getName());   
    12. "停止:"
    13. false);   
    14. true;   
    15.           }   
    16.       }   
    17.   });   
    18. /* 播放 */
    19. new
    20. @Override
    21. public void
    22. // TODO Auto-generated method stub 
    23. if (iPlayFile != null
    24. /* 打开播放程序 */
    25.               openFile(iPlayFile);   
    26.           }   
    27.       }   
    28.   });   
    29. /* 删除 */
    30. new
    31. @Override
    32. public void
    33. // TODO Auto-generated method stub 
    34. if (iPlayFile != null) {   
    35. /* 先将Adapter删除文件名 */
    36.               iAdapter.remove(iPlayFile.getName());   
    37. /* 删除文件 */
    38. if
    39.                   iPlayFile.delete();   
    40. "删除完成");   
    41.           }   
    42.       }   
    43.   });   
    44.   
    45. new
    46. @Override
    47. public void onItemClick(AdapterView<?> arg0, View arg1, int
    48. long
    49. /* 当有点击文件名时将删除及播放按钮Enable */
    50. true);   
    51. true);   
    52. new
    53.                   + File.separator + ((CheckedTextView) arg1).getText());   
    54. "您选择的是:"
    55.       }   
    56.   });

     

    在Activity的onStop()方法也要加进去释放iMediaRecorder的语句。


      1. @Override
      2. protected void
      3. if (iMediaRecorder != null
      4. /* 停止录音 */
      5.             iMediaRecorder.stop();   
      6.             iMediaRecorder.release();   
      7. null;   
      8.         }   
      9. super.onStop();   
      10.     }   
      11.   
      12. 这是一个自定义方法,目的是从手机存储卡中取出以.amr结尾的文件。   
      13. private void
      14. new
      15. if
      16.             File files[] = iRecAudioDir.listFiles();   
      17. if (files != null) {   
      18. for (int i = 0; i < files.length; i++) {   
      19. if (files[i].getName().indexOf(".") >= 0) {   
      20.                         String fileS = files[i].getName().substring(   
      21. "."));   
      22. if (fileS.toLowerCase().equals(".amr"))   
      23.                             iRecordFiles.add(files[i].getName());   
      24.                     }   
      25.                 }   
      26.             }   
      27.         }   
      28.     }

      调用系统自带播放器来播放刚才录制好的声音片段。OPhone系统会根据文件类型来自动决定使用何种工具来打开对应的文件。当然我们还可以用OPhone提供的MediaPlayer类来实现声音片段的播放,由于篇幅有限,这里不再介绍。

       


      1. private void
      2. new
      3.     intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);   
      4.     intent.setAction(android.content.Intent.ACTION_VIEW);   
      5.     String type = getMIMEType(aFile);   
      6.     intent.setDataAndType(Uri.fromFile(aFile), type);   
      7.     startActivity(intent);   
      8. }   
      9.   
      10. private
      11.     String end = aFile.getName().substring(   
      12. ".") + 1, aFile.getName().length())   
      13.             .toLowerCase();   
      14. "";   
      15. if (end.equals("mp3") || end.equals("aac") || end.equals("aac")   
      16. "amr") || end.equals("mpeg") || end.equals("mp4")) {   
      17. "audio";   
      18. else if (end.equals("jpg") || end.equals("gif") || end.equals("png")   
      19. "jpeg")) {   
      20. "image";   
      21. else
      22. "*";   
      23.     }   
      24. "/*";   
      25. return
      26. }

      添加权限许可

      如果只是写好了程序还不算完工,最后我们需要在AndroidManifest.xml文件中将程序的录音权限打开!这样才能成为一个完整的程序。

       



        1. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        2. android:versionCode="1"
        3. android:versionName="1.0" package="com.ophone.iRecorder">
        4.      <application  
        5. android:icon="@drawable/icon"
        6. android:label="@string/app_name">
        7.         <activity android:name=".ActivityMain"
        8. android:label="@string/app_name">
        9.             <intent-filter>  
        10.                 <action  
        11. android:name="android.intent.action.MAIN" />
        12.                 <category  
        13. android:name="android.intent.category.LAUNCHER" />
        14.             </intent-filter>  
        15.         </activity>  
        16.     </application>  
        17. <uses-permission android:name="android.permission.RECORD_AUDIO">
        18. </uses-permission>  
        19. </manifest>

        总结

        本文介绍了如何在OPhone系统中使用MediaRecorder来实现录音功能,以及MediaRecorder常用方法的使用和使用MediaRecorder的时候在授权时应注意的事项,希望对大家有所帮助。