1. 程式人生 > >Android 錄音實現方法、仿微信語音、麥克風錄音、傳送語音

Android 錄音實現方法、仿微信語音、麥克風錄音、傳送語音

效果圖(注!由於使用的模擬器錄製,所以圖片中的錄音時候話筒上下波動比較小,手機上正常!):

這裡寫圖片描述



使用方法:



錄音工具類:AudioRecoderUtils.java,程式碼如下:

public class AudioRecoderUtils {

    //檔案路徑
    private String filePath;
    //資料夾路徑
    private String FolderPath;

    private MediaRecorder mMediaRecorder;
    private final String TAG = "fan";
    public static
final int MAX_LENGTH = 1000 * 60 * 10;// 最大錄音時長1000*60*10; private OnAudioStatusUpdateListener audioStatusUpdateListener; /** * 檔案儲存預設sdcard/record */ public AudioRecoderUtils(){ //預設儲存路徑為/sdcard/record/下 this(Environment.getExternalStorageDirectory()+"/record/"); } public
AudioRecoderUtils(String filePath) { File path = new File(filePath); if(!path.exists()) path.mkdirs(); this.FolderPath = filePath; } private long startTime; private long endTime; /** * 開始錄音 使用amr格式 * 錄音檔案 * @return */ public
void startRecord() { // 開始錄音 /* ①Initial:例項化MediaRecorder物件 */ if (mMediaRecorder == null) mMediaRecorder = new MediaRecorder(); try { /* ②setAudioSource/setVedioSource */ mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);// 設定麥克風 /* ②設定音訊檔案的編碼:AAC/AMR_NB/AMR_MB/Default 聲音的(波形)的取樣 */ mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT); /* * ②設定輸出檔案的格式:THREE_GPP/MPEG-4/RAW_AMR/Default THREE_GPP(3gp格式 * ,H263視訊/ARM音訊編碼)、MPEG-4、RAW_AMR(只支援音訊且音訊編碼要求為AMR_NB) */ mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); filePath = FolderPath + TimeUtils.getCurrentTime() + ".amr" ; /* ③準備 */ mMediaRecorder.setOutputFile(filePath); mMediaRecorder.setMaxDuration(MAX_LENGTH); mMediaRecorder.prepare(); /* ④開始 */ mMediaRecorder.start(); // AudioRecord audioRecord. /* 獲取開始時間* */ startTime = System.currentTimeMillis(); updateMicStatus(); Log.e("fan", "startTime" + startTime); } catch (IllegalStateException e) { Log.i(TAG, "call startAmr(File mRecAudioFile) failed!" + e.getMessage()); } catch (IOException e) { Log.i(TAG, "call startAmr(File mRecAudioFile) failed!" + e.getMessage()); } } /** * 停止錄音 */ public long stopRecord() { if (mMediaRecorder == null) return 0L; endTime = System.currentTimeMillis(); //有一些網友反應在5.0以上在呼叫stop的時候會報錯,翻閱了一下谷歌文件發現上面確實寫的有可能會報錯的情況,捕獲異常清理一下就行了,感謝大家反饋! try { mMediaRecorder.stop(); mMediaRecorder.reset(); mMediaRecorder.release(); mMediaRecorder = null; audioStatusUpdateListener.onStop(filePath); filePath = ""; }catch (RuntimeException e){ mMediaRecorder.reset(); mMediaRecorder.release(); mMediaRecorder = null; File file = new File(filePath); if (file.exists()) file.delete(); filePath = ""; } return endTime - startTime; } /** * 取消錄音 */ public void cancelRecord(){ try { mMediaRecorder.stop(); mMediaRecorder.reset(); mMediaRecorder.release(); mMediaRecorder = null; }catch (RuntimeException e){ mMediaRecorder.reset(); mMediaRecorder.release(); mMediaRecorder = null; } File file = new File(filePath); if (file.exists()) file.delete(); filePath = ""; } private final Handler mHandler = new Handler(); private Runnable mUpdateMicStatusTimer = new Runnable() { public void run() { updateMicStatus(); } }; private int BASE = 1; private int SPACE = 100;// 間隔取樣時間 public void setOnAudioStatusUpdateListener(OnAudioStatusUpdateListener audioStatusUpdateListener) { this.audioStatusUpdateListener = audioStatusUpdateListener; } /** * 更新麥克狀態 */ private void updateMicStatus() { if (mMediaRecorder != null) { double ratio = (double)mMediaRecorder.getMaxAmplitude() / BASE; double db = 0;// 分貝 if (ratio > 1) { db = 20 * Math.log10(ratio); if(null != audioStatusUpdateListener) { audioStatusUpdateListener.onUpdate(db,System.currentTimeMillis()-startTime); } } mHandler.postDelayed(mUpdateMicStatusTimer, SPACE); } } public interface OnAudioStatusUpdateListener { /** * 錄音中... * @param db 當前聲音分貝 * @param time 錄音時長 */ public void onUpdate(double db,long time); /** * 停止錄音 * @param filePath 儲存路徑 */ public void onStop(String filePath); } }
  • 1

使用很簡單,主要就是開始錄音startRecord()、取消錄音cancelRecord()、結束錄音stopRecord()和錄音監聽setOnAudioStatusUpdateListener(),注意,取消錄音不儲存檔案,結束錄音會儲存檔案!


在佈局檔案中新增一個控制元件(任意一個都行)

<Button
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:text="按住說話"
  android:textColor="@android:color/white"
  android:id="@+id/button"
  android:background="@color/colorPrimary"
   />
  • 1





Activity中使用:

        //當前佈局檔案的根layout
        final RelativeLayout rl = (RelativeLayout) findViewById(R.id.rl);

        mButton = (Button) findViewById(R.id.button);

        //PopupWindow的佈局檔案
        final View view = View.inflate(this, R.layout.layout_microphone, null);

        final PopupWindowFactory mPop = new PopupWindowFactory(this,view);

        //PopupWindow佈局檔案裡面的控制元件
        mImageView = (ImageView) view.findViewById(R.id.iv_recording_icon);
        mTextView = (TextView) view.findViewById(R.id.tv_recording_time);

        mAudioRecoderUtils = new AudioRecoderUtils();

        //錄音回撥
        mAudioRecoderUtils.setOnAudioStatusUpdateListener(new AudioRecoderUtils.OnAudioStatusUpdateListener() {

            //錄音中....db為聲音分貝,time為錄音時長
            @Override
            public void onUpdate(double db, long time) {
                //根據分貝值來設定錄音時話筒圖示的上下波動,下面有講解
                mImageView.getDrawable().setLevel((int) (3000 + 6000 * db / 100));
                mTextView.setText(TimeUtils.long2String(time));
            }

            //錄音結束,filePath為儲存路徑
            @Override
            public void onStop(String filePath) {
                Toast.makeText(MainActivity.this, "錄音儲存在:" + filePath, Toast.LENGTH_SHORT).show();
                mTextView.setText(TimeUtils.long2String(0));
            }
        });

        //Button的touch監聽
        mButton.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {

                switch (event.getAction()){

                    case MotionEvent.ACTION_DOWN:

                        mPop.showAtLocation(rl,Gravity.CENTER,0,0);

                        mButton.setText("鬆開儲存");
                        mAudioRecoderUtils.startRecord();


                        break;

                    case MotionEvent.ACTION_UP:

                        mAudioRecoderUtils.stopRecord();        //結束錄音(保存錄音檔案)
//                        mAudioRecoderUtils.cancelRecord();    //取消錄音(不保存錄音檔案)
                        mPop.dismiss();
                        mButton.setText("按住說話");

                        break;
                }
                return true;
            }
        });
  • 1

OK,就這麼簡單,demo下載:點選免費下載

下面放一個原作者的封裝好的自定義的View,繼承自Button,直接放入佈局檔案後,就可以使用,並封裝好了PopupWindow,使用更簡單,至於兩種方式的好壞看個人需求

效果圖:

這裡寫圖片描述


使用:


佈局中引入就行了:

<cn.zeffectn.view.recordbutton.view.RecordButton
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:text="錄音按鈕"
     android:id="@+id/button"
     android:layout_alignParentTop="true"
     android:layout_alignParentLeft="true"
     android:layout_alignParentStart="true" />
  • 1

oK,完了,demo下載:點選免費下載




文字所有下載(已上傳新Demo,新增6.0許可權申請):第一個Demo | 第二個Demo