VoiceManager的封裝

這是一個(gè)錄音和播放封裝,我們有一個(gè)封裝類:
VoiceManager.class,我們播放音樂(lè)窄做,我們的view也需要對(duì)應(yīng)的變化,音樂(lè)來(lái)控制我們ui控件的變化也就是我們的時(shí)間來(lái)控制我們的ui變化枣购,所以我們需要的一個(gè)計(jì)算時(shí)間的工具類剥汤,也就是我們的VoiceTimeUtils.class

1.播放錄音的工具類--- MediaPlayer
(注意,我們可以看到在準(zhǔn)備播放的方法里面每一個(gè)返回的是布爾值允睹,當(dāng)我們的播放方法執(zhí)行了的時(shí)候就會(huì)放回true运准,沒(méi)有執(zhí)行的時(shí)候幌氮,放回的是false,這個(gè)點(diǎn)子很好胁澳,值得我們記赘没ァ!)

  • 準(zhǔn)備工作:
  /**
     * 播放錄音準(zhǔn)備工作
     */
    private boolean prepareMedia(MediaPlayer mp,String file){
        boolean result = false;
        try {
            mp.setDataSource(file);
            mp.prepare();
            result = true;
        } catch (Exception e) {
        }

        return result;
    }

 /**
     * 播放錄音開(kāi)始
     * @param mp
     * @return
     */
    private boolean playMedia(MediaPlayer mp){
        boolean result = false;
        try {
            if (mp != null) {
                mp.start();
                result = true;
            }
        } catch (Exception e) {
        }

        return result;
    }

 /**
     * 停止播放
     * @param mp
     * @param release
     * @return
     */
    private boolean stopMedia(MediaPlayer mp,boolean release){
        boolean result = false;
        try {
            if (mp != null) {
                mp.stop();

                if (release) {
                    mp.release();


                }
                result = true;
            }
        } catch (Exception e) {
        }

        return result;
    }

 /**
     * 暫停播放
     * @param mp
     * @return
     */
    private boolean pauseMedia(MediaPlayer mp){
        boolean result = false;

        try {
            if (mp != null) {
                mp.pause();
                result = true;
            }
        } catch (Exception e) {
        }

        return result;
    }

此外我們開(kāi)啟一個(gè)線程來(lái)檢測(cè)我們的錄音聲音頻率的大芯禄:
(可以看到我們這個(gè)類中定義了一個(gè)方法叫exit他里面控制一個(gè)布爾值為false慢洋,然后在我們的run方法中用while循環(huán)來(lái)檢測(cè)我們exit方法里面布爾值是否為false,如果為false就停止錄音陆盘,否則就一直錄音)

  /**
     * 監(jiān)聽(tīng)錄音聲音頻率大小
     */
     private class ObtainDecibelThread extends Thread{
        private volatile boolean running = true;

        public void exit() {
            running = false;
        }
        @Override
        public void run() {
            while (running) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if (mMediaRecorder == null || !running) {
                    break;
                }
                try {
                    final double ratio = mMediaRecorder.getMaxAmplitude()/150;
                    if (ratio != 0&&voiceRecordCallBack!=null) {
                        ((Activity)context).runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                double db=0;// 分貝
                                if (ratio > 1)
                                    db = (int) (20 * Math.log10(ratio));
                                voiceRecordCallBack.recVoiceGrade((int)db);
                            }
                        });
                    }
                } catch (RuntimeException e) {
                    e.printStackTrace();
                }

            }
        }
     }

2 . 我們的錄音的工具類是我們的---MediaRecorder
(可以看到我們的錄音準(zhǔn)備方法里面普筹,回調(diào)的是我們的文件存放地址,這個(gè)就很機(jī)智了隘马,還有就是我們的錄音準(zhǔn)備工作要設(shè)置的配置太防,我們簡(jiǎn)單縮寫(xiě)一下就是,ASM,AEA,UFR,還有一個(gè)就是設(shè)置我們的地址)

  • 準(zhǔn)備工作:
1. 判斷我們的錄音的存放地址是否是正確:

   public static File recAudioDir(String path) {
       File file = new File(path);
       if (!file.exists()) {
           file.mkdirs();
       }
       return file;
   }

/**
    * 錄音準(zhǔn)備工作 酸员,開(kāi)始錄音
    *
    * @param mr
    * @param start
    * @return
    */
   @SuppressWarnings("deprecation")
   private File prepareRecorder(MediaRecorder mr, boolean start) {
       File recFile = null;
       if (mr == null) return null;
       try {
           String path = recAudioDir(recordFilePath).getAbsolutePath();
           recFile = new File(path, VoiceTimeUtils.getTime() + ".amr");
           mr.setAudioSource(MediaRecorder.AudioSource.MIC);
           mr.setOutputFormat(MediaRecorder.OutputFormat.RAW_AMR);
           mr.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
           mr.setOutputFile(recFile.getAbsolutePath());
           mr.prepare();
           if (start) {
               mr.start();
               if (mThread == null) {
                   mThread = new ObtainDecibelThread();
                   mThread.start();
               }
           }
       } catch (Exception e) {
           e.printStackTrace();
       }
       return recFile;

   }

   /**
    * 停止錄音和播放
    */
   public void stopRecordAndPlay(){
       stopRecorder(mMediaRecorder, true);
       mMediaRecorder = null;
       stopMedia(mMediaPlayer, true);
       mMediaPlayer = null;
   }

第二部分 接口

 /**
     * 錄音回調(diào)監(jiān)聽(tīng)
     */
    public interface VoiceRecordCallBack{
        //錄音中
        void recDoing(long time,String strTime);
        //錄音中的聲音頻率等級(jí);
        void recVoiceGrade(int grade);
        //錄音開(kāi)始
        void recStart(boolean init);
        //錄音暫停
        void recPause(String str);
        //錄音結(jié)束
        void recFinish(long lenth,String strLenth,String path);
    }

 /**
     * 播放錄音回調(diào)監(jiān)聽(tīng)
     */
    public interface VoicePlayCallBack{
        /**
         * 音頻長(zhǎng)度
         * 指定的某個(gè)時(shí)間段蜒车,以秒為單位
         */
        void voiceTotalLenth(long time,String strTime);
        /**
         * 播放中
         * 指定的某個(gè)時(shí)間段,以秒為單位
         */
        void playDoing (long time,String strTime);
        //播放暫停
        void playPause();
        //播放開(kāi)始
        void playStart();
        //播放結(jié)束
        void  playFinish();
    }

附加一個(gè)我們判斷我們的sd卡是否存在:
 /**
     * SD卡是否可用
     */
    public static boolean isSDCardAvailable() {
        return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState());
    }

3.第三部分 具體代碼

上面我們完成了我們的準(zhǔn)備工作幔嗦,現(xiàn)在開(kāi)始我們的具體代碼:

public class VoiceManager {

    public final int MSG_TIME_INTERVAL = 100;

    private static VoiceManager voiceManager =null;
    private Context context;
    private VoiceRecordCallBack voiceRecordCallBack;
    private VoicePlayCallBack voicePlayCallBack;
    private SeekBar mSBPlayProgress;

    // 多媒體例如聲音的狀態(tài)
    public final int MEDIA_STATE_UNDEFINE = 200;
    public final int MEDIA_STATE_RECORD_STOP = 210;
    public final int MEDIA_STATE_RECORD_DOING = 220;
    public final int MEDIA_STATE_RECORD_PAUSE = 230;
    public final int MEDIA_STATE_PLAY_STOP = 310;
    public final int MEDIA_STATE_PLAY_DOING = 320;
    public final int MEDIA_STATE_PLAY_PAUSE = 330;

    private MediaRecorder mMediaRecorder = null;
    private MediaPlayer mMediaPlayer = null;

    private String mRecTimePrev;
    private long mRecTimeSum = 0;

    private int mSavedState, mDeviceState = MEDIA_STATE_UNDEFINE;

    private ArrayList<File> mRecList = new ArrayList<File>();

    private ObtainDecibelThread mThread;

    /**
     * 錄音文件存放的位置(文件夾)
     */
    private String recordFilePath = "";
    /**
     * 播放音頻文件位置
     */
    private String playFilePath;

    private VoiceManager(Context context){
        this.context = context;
    }

    public static VoiceManager getInstance(Context context){
        if(voiceManager == null){
            synchronized (VoiceManager.class){
                if(voiceManager == null){
                    voiceManager = new VoiceManager(context);
                }
            }
        }
        return voiceManager;
    }

    /**
     * 播放器結(jié)束監(jiān)聽(tīng)
     */
    private MediaPlayer.OnCompletionListener mPlayCompetedListener = new MediaPlayer.OnCompletionListener(){

        @Override
        public void onCompletion(MediaPlayer mediaPlayer) {
            mDeviceState = MEDIA_STATE_PLAY_STOP;
            mHandler.removeMessages(MSG_TIME_INTERVAL);
            mMediaPlayer.stop();
            mMediaPlayer.release();
            if (mSBPlayProgress != null) {
                mSBPlayProgress.setProgress(0);
            }
            if (voicePlayCallBack != null) {
                voicePlayCallBack.playFinish();
            }
        }
    };
    /**
     * 播放或錄音handler
     */
    @SuppressLint("HandlerLeak")
    private final Handler mHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            VoiceTimeUtils ts;
            int current;
            try {
                switch (msg.what) {
                    case MSG_TIME_INTERVAL:
                        //錄音
                        if(mDeviceState == MEDIA_STATE_RECORD_DOING){
                            ts = VoiceTimeUtils.timeSpanToNow(mRecTimePrev);
                            mRecTimeSum += ts.mDiffSecond;
                            mRecTimePrev = VoiceTimeUtils.getTimeStrFromMillis(ts.mNowTime);
                            ts = VoiceTimeUtils.timeSpanSecond(mRecTimeSum);
                            //回調(diào)錄音時(shí)間
                            if (voiceRecordCallBack != null) {
                                voiceRecordCallBack.recDoing(mRecTimeSum, String.format("%02d:%02d:%02d",
                                        ts.mSpanHour, ts.mSpanMinute, ts.mSpanSecond));
                            }
                            mHandler.sendEmptyMessageDelayed(MSG_TIME_INTERVAL, 1000);
                        }
                        //播放
                        else if (mDeviceState == MEDIA_STATE_PLAY_DOING) {
                            current = mMediaPlayer.getCurrentPosition();
                            if (mSBPlayProgress != null) {
                                mSBPlayProgress.setProgress(current);
                            }
                            ts = VoiceTimeUtils.timeSpanSecond(current / 1000);
                            //回調(diào)播放進(jìn)度
                            if (voicePlayCallBack != null) {
                                voicePlayCallBack.playDoing(current / 1000, String.format("%02d:%02d:%02d",
                                        ts.mSpanHour, ts.mSpanMinute, ts.mSpanSecond));
                            }
                            mHandler.sendEmptyMessageDelayed(MSG_TIME_INTERVAL, 1000);
                        }
                        break;
                    default:
                        break;
                }
            } catch (Exception e) {
            }
        }
    };
    /*********************************錄音操作begin***************************/
    /**
     * 設(shè)置錄音監(jiān)聽(tīng)
     * @param callback
     */
      public void setVoiceRecordListener(VoiceRecordCallBack callback){
         this.voiceRecordCallBack = callback;
     }

    /**
     * 開(kāi)始錄音(外部調(diào)用)
     * @param filePath
     */
     public void startVoiceRecord(String filePath){
         if (!isSDCardAvailable()) return ;
         this.recordFilePath = filePath;
         startVoiceRecord(true);
     }

    /**
     * 繼續(xù)或暫停錄音
     */
    public void pauseOrStartVoiceRecord(){
        if (mDeviceState == MEDIA_STATE_RECORD_DOING) {
            mDeviceState = MEDIA_STATE_RECORD_PAUSE;
            stopRecorder(mMediaRecorder, true);
            mMediaRecorder = null;
            voiceRecordCallBack.recPause("已暫停");
        } else {
            startVoiceRecord(false);
        }
     }

    /**
     * 完成錄音
      */
     public void stopVoiceRecord(){
         try {
             mHandler.removeMessages(MSG_TIME_INTERVAL);
             mDeviceState = MEDIA_STATE_RECORD_STOP;
             stopRecorder(mMediaRecorder, true);
             mMediaRecorder = null;
             if (VoiceTimeUtils.timeSpanSecond(mRecTimeSum).mSpanSecond == 0) {
                 Toast.makeText(context, "時(shí)間過(guò)短", Toast.LENGTH_SHORT).show();
             } else {
                 File file = getOutputVoiceFile(mRecList);
                 if (file != null && file.length() > 0) {
                     cleanFieArrayList(mRecList);
                     //TODO 這里可以返回?cái)?shù)據(jù) setResult
                     final VoiceTimeUtils ts = VoiceTimeUtils.timeSpanSecond(mRecTimeSum);
                     //完成錄音
                     if (voiceRecordCallBack != null) {
                         voiceRecordCallBack.recFinish(mRecTimeSum, String.format("%02d:%02d:%02d",
                                 ts.mSpanHour, ts.mSpanMinute, ts.mSpanSecond),file.getAbsolutePath());
                     }
                 }
             }

         } catch (Exception e) {
             e.printStackTrace();
         }
     }

    /**
     * 開(kāi)始錄音(內(nèi)部調(diào)用)
     * @param init
     */
     private void startVoiceRecord(boolean init){
         if (!isSDCardAvailable()) return;
         if (init) {
             mRecTimeSum = 0;
             cleanFieArrayList(mRecList);
         }
         //錄音前停止播放回調(diào)
         if(voicePlayCallBack!=null){
             voicePlayCallBack.playFinish();
         }
         stopRecorder(mMediaRecorder, true);
         mMediaRecorder = null;

         stopMedia(mMediaPlayer, true);
         mMediaPlayer = null;
         mMediaRecorder = new MediaRecorder();
         File file = prepareRecorder(mMediaRecorder, true);
         if (file != null) {
             //開(kāi)始錄音回調(diào)
             if (voiceRecordCallBack != null) {
                 voiceRecordCallBack.recStart(init);
             }
             mDeviceState = MEDIA_STATE_RECORD_DOING;
             mRecTimePrev = VoiceTimeUtils.getTimeStrFromMillis(System.currentTimeMillis());
             mRecList.add(file);

             mHandler.removeMessages(MSG_TIME_INTERVAL);
             mHandler.sendEmptyMessage(MSG_TIME_INTERVAL);
         }

     }

    /**
     * 監(jiān)聽(tīng)錄音聲音頻率大小
     */
     private class ObtainDecibelThread extends Thread{
        private volatile boolean running = true;

        public void exit() {
            running = false;
        }
        @Override
        public void run() {
            while (running) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if (mMediaRecorder == null || !running) {
                    break;
                }
                try {
                    final double ratio = mMediaRecorder.getMaxAmplitude()/150;
                    if (ratio != 0&&voiceRecordCallBack!=null) {
                        ((Activity)context).runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                double db=0;// 分貝
                                if (ratio > 1)
                                    db = (int) (20 * Math.log10(ratio));
                                voiceRecordCallBack.recVoiceGrade((int)db);
                            }
                        });
                    }
                } catch (RuntimeException e) {
                    e.printStackTrace();
                }

            }
        }
     }

    /**
     * 合并錄音
     * @param list
     * @return
     */
     private File getOutputVoiceFile(ArrayList<File> list){
         String mMinute1 = VoiceTimeUtils.getTime();
         File recDirFile = recAudioDir(recordFilePath);

         // 創(chuàng)建音頻文件,合并的文件放這里
         File resFile = new File(recDirFile, mMinute1 + ".amr");
         FileOutputStream fileOutputStream = null;
         try {
             fileOutputStream = new FileOutputStream(resFile);
         } catch (IOException e) {
         }
         // list里面為暫停錄音 所產(chǎn)生的 幾段錄音文件的名字酿愧,中間幾段文件的減去前面的6個(gè)字節(jié)頭文件
         for (int i = 0; i < list.size(); i++) {
             File file = list.get(i);
             try {
                 FileInputStream fileInputStream = new FileInputStream(file);
                 byte[] myByte = new byte[fileInputStream.available()];
                 // 文件長(zhǎng)度
                 int length = myByte.length;
                 // 頭文件
                 if (i == 0) {
                     while (fileInputStream.read(myByte) != -1) {
                         fileOutputStream.write(myByte, 0, length);
                     }
                 }
                 // 之后的文件,去掉頭文件就可以了
                 else {
                     while (fileInputStream.read(myByte) != -1) {
                         fileOutputStream.write(myByte, 6, length - 6);
                     }
                 }
                 fileOutputStream.flush();
                 fileInputStream.close();
             } catch (Exception e) {
                 e.printStackTrace();
             }
         }
         // 結(jié)束后關(guān)閉流
         try {
             fileOutputStream.close();
         } catch (IOException e) {
             e.printStackTrace();
         }

         return resFile;

     }

    /**
     * 清空暫停錄音所產(chǎn)生的幾段錄音文件
     * @param list
     */
     private void cleanFieArrayList(ArrayList<File> list){
         for (File file : list) {
             file.delete();
         }
         list.clear();
     }

    /*********************************錄音操作end***************************/


    /*********************************播放操作end***************************/
      public void setVoicePlayListener(VoicePlayCallBack callback){
          voicePlayCallBack = callback;
     }

    /**
     * 播放SeekBar監(jiān)聽(tīng)
     * @param seekBar
     */
     public void setSeekBarListener(SeekBar seekBar){
         mSBPlayProgress = seekBar;
         if (mSBPlayProgress != null) {
             mSBPlayProgress.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                 @Override
                 public void onStartTrackingTouch(SeekBar seekBar) {
                     mHandler.removeMessages(MSG_TIME_INTERVAL);
                     mSavedState = mDeviceState;
                     if (mSavedState == MEDIA_STATE_PLAY_DOING) {
                         pauseMedia(mMediaPlayer);
                     }
                 }

                 @Override
                 public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                     mHandler.removeMessages(MSG_TIME_INTERVAL);
                     VoiceTimeUtils ts = VoiceTimeUtils.timeSpanSecond(progress / 1000);
                     //播放進(jìn)度
                     if (voicePlayCallBack != null) {
                         voicePlayCallBack.playDoing(progress / 1000, String.format("%02d:%02d:%02d",
                                 ts.mSpanHour, ts.mSpanMinute, ts.mSpanSecond));
                     }
                 }

                 @Override
                 public void onStopTrackingTouch(SeekBar seekBar) {
                     seekMedia(mMediaPlayer, mSBPlayProgress.getProgress());

                     if (mSavedState == MEDIA_STATE_PLAY_DOING) {
                         playMedia(mMediaPlayer);
                         mHandler.sendEmptyMessage(MSG_TIME_INTERVAL);
                     }
                 }
             });
         }

     }

    /**
     * 開(kāi)始播放(外部調(diào)用)
     * @param filePath
     */
     public void startPlay(String filePath){
         if (TextUtils.isEmpty(filePath)|| !new File(filePath).exists())
         {
             if (voicePlayCallBack != null) {
                 voicePlayCallBack.playFinish();
             }
             Toast.makeText(context,"文件不存在",Toast.LENGTH_SHORT).show();
             return;
         }else {
             playFilePath = filePath;
             startPlay(true);
         }

     }

    /**
     * 開(kāi)始播放(內(nèi)部調(diào)用)
     * @param init
     */
     private void startPlay(boolean init){
         try {
             stopRecorder(mMediaRecorder, true);
             mMediaRecorder = null;

             stopMedia(mMediaPlayer, true);
             mMediaPlayer = null;

             mMediaPlayer = new MediaPlayer();
             mMediaPlayer.setOnCompletionListener(mPlayCompetedListener);

             if (prepareMedia(mMediaPlayer, playFilePath)) {
                 mDeviceState = MEDIA_STATE_PLAY_DOING;
                 //總時(shí)間長(zhǎng)度
                 long totalTime = mMediaPlayer.getDuration() / 1000;
                 VoiceTimeUtils ts = VoiceTimeUtils.timeSpanSecond(totalTime);
                 String voiceLength = String.format("%02d:%02d:%02d",
                         ts.mSpanHour, ts.mSpanMinute, ts.mSpanSecond);
                 //播放進(jìn)度回調(diào)
                 if (voicePlayCallBack != null) {
                     voicePlayCallBack.voiceTotalLenth(totalTime, voiceLength);
                     voicePlayCallBack.playDoing(0, "00:00:00");
                 }
                 if (mSBPlayProgress != null) {
                     mSBPlayProgress.setMax(Math.max(1, mMediaPlayer.getDuration()));
                 }
                 if (init) {
                     if (mSBPlayProgress != null) {
                         mSBPlayProgress.setProgress(0);
                     }
                     seekMedia(mMediaPlayer, 0);
                 } else {
                     seekMedia(mMediaPlayer, mSBPlayProgress.getProgress());
                 }
                 if (playMedia(mMediaPlayer)) {
                     mHandler.removeMessages(MSG_TIME_INTERVAL);
                     mHandler.sendEmptyMessage(MSG_TIME_INTERVAL);
                 }
             }
         } catch (Exception e) {
             Log.e("播放出錯(cuò)了", e.getMessage());
         }

     }

    /**
     * 繼續(xù)暫停
     */
    public void continueOrPausePlay(){
        if (mDeviceState == MEDIA_STATE_PLAY_DOING) {
            mDeviceState = MEDIA_STATE_PLAY_PAUSE;
            pauseMedia(mMediaPlayer);
            //暫停
            if (voicePlayCallBack != null) {
                voicePlayCallBack.playPause();
            }
        } else if (mDeviceState == MEDIA_STATE_PLAY_PAUSE) {
            mDeviceState = MEDIA_STATE_PLAY_DOING;
            playMedia(mMediaPlayer);
            //播放中
            mHandler.removeMessages(MSG_TIME_INTERVAL);
            mHandler.sendEmptyMessage(MSG_TIME_INTERVAL);
        } else if (mDeviceState == MEDIA_STATE_PLAY_STOP) {
            //播放
            if (!TextUtils.isEmpty(playFilePath)) {
                startPlay(false);
            }
        }

     }

    /**
     * 停止播放
     */
    public void stopPlay(){
        mHandler.removeMessages(MSG_TIME_INTERVAL);
        mDeviceState = MEDIA_STATE_PLAY_STOP;
        stopMedia(mMediaPlayer, true);
        mMediaPlayer = null;
     }

    /**
     * 是否在播放中
     * @return
     */
     public boolean isPlaying(){
         return mDeviceState == MEDIA_STATE_PLAY_DOING;
     }

    /*********************************播放操作end***************************/

    /**
     * 播放錄音準(zhǔn)備工作
     */
    private boolean prepareMedia(MediaPlayer mp,String file){
        boolean result = false;
        try {
            mp.setDataSource(file);
            mp.prepare();
            result = true;
        } catch (Exception e) {
        }

        return result;
    }

    /**
     * 播放錄音開(kāi)始
     * @param mp
     * @return
     */
    private boolean playMedia(MediaPlayer mp){
        boolean result = false;
        try {
            if (mp != null) {
                mp.start();
                result = true;
            }
        } catch (Exception e) {
        }

        return result;
    }

    /**
     * 拖動(dòng)播放進(jìn)度條
     * @param mp
     * @param pos
     * @return
     */
    private boolean seekMedia(MediaPlayer mp,int pos){
        boolean result = false;
        try {
            if (mp != null && pos >= 0) {
                mp.seekTo(pos);
                result = true;
            }
        } catch (Exception e) {
        }
        return result;
    }

    /**
     * 停止播放
     * @param mp
     * @param release
     * @return
     */
    private boolean stopMedia(MediaPlayer mp,boolean release){
        boolean result = false;
        try {
            if (mp != null) {
                mp.stop();

                if (release) {
                    mp.release();


                }
                result = true;
            }
        } catch (Exception e) {
        }

        return result;
    }

    /**
     * 暫停播放
     * @param mp
     * @return
     */
    private boolean pauseMedia(MediaPlayer mp){
        boolean result = false;

        try {
            if (mp != null) {
                mp.pause();
                result = true;
            }
        } catch (Exception e) {
        }

        return result;
    }

    private boolean stopRecorder(MediaRecorder mr, boolean release) {
        boolean result = false;
        try {
            if (mr != null) {
                mr.stop();
                if (release) {
                    mr.release();
                }
                result = true;
            }
            if(mThread!=null){
                mThread.exit();
                mThread=null;
            }
        } catch (Exception e) {
            if(mThread!=null){
                mThread=null;
                mThread.exit();
            }
        }
        return result;

    }

    /**
     * 錄音準(zhǔn)備工作 邀泉,開(kāi)始錄音
     *
     * @param mr
     * @param start
     * @return
     */
    @SuppressWarnings("deprecation")
    private File prepareRecorder(MediaRecorder mr, boolean start) {
        File recFile = null;
        if (mr == null) return null;
        try {
            String path = recAudioDir(recordFilePath).getAbsolutePath();
            recFile = new File(path, VoiceTimeUtils.getTime() + ".amr");
            mr.setAudioSource(MediaRecorder.AudioSource.MIC);
            mr.setOutputFormat(MediaRecorder.OutputFormat.RAW_AMR);
            mr.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
            mr.setOutputFile(recFile.getAbsolutePath());
            mr.prepare();
            if (start) {
                mr.start();
                if (mThread == null) {
                    mThread = new ObtainDecibelThread();
                    mThread.start();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return recFile;

    }

    /**
     * 停止錄音和播放
     */
    public void stopRecordAndPlay(){
        stopRecorder(mMediaRecorder, true);
        mMediaRecorder = null;
        stopMedia(mMediaPlayer, true);
        mMediaPlayer = null;
    }

    /**
     * 錄音回調(diào)監(jiān)聽(tīng)
     */
    public interface VoiceRecordCallBack{
        //錄音中
        void recDoing(long time,String strTime);
        //錄音中的聲音頻率等級(jí);
        void recVoiceGrade(int grade);
        //錄音開(kāi)始
        void recStart(boolean init);
        //錄音暫停
        void recPause(String str);
        //錄音結(jié)束
        void recFinish(long lenth,String strLenth,String path);
    }
    /**
     * 播放錄音回調(diào)監(jiān)聽(tīng)
     */
    public interface VoicePlayCallBack{
        /**
         * 音頻長(zhǎng)度
         * 指定的某個(gè)時(shí)間段嬉挡,以秒為單位
         */
        void voiceTotalLenth(long time,String strTime);
        /**
         * 播放中
         * 指定的某個(gè)時(shí)間段,以秒為單位
         */
        void playDoing (long time,String strTime);
        //播放暫停
        void playPause();
        //播放開(kāi)始
        void playStart();
        //播放結(jié)束
        void  playFinish();
    }

    /**
     * SD卡是否可用
     */
    public static boolean isSDCardAvailable() {
        return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState());
    }

    public static File recAudioDir(String path) {
        File file = new File(path);
        if (!file.exists()) {
            file.mkdirs();
        }
        return file;
    }
}

本項(xiàng)目的url地址:
https://github.com/jaydenxiao2016/VoiceManager/blob/master/app/src/main/java/com/jaydenxiao/voicemanager/RecordVoiceButton.java

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末汇恤,一起剝皮案震驚了整個(gè)濱河市庞钢,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌因谎,老刑警劉巖基括,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異财岔,居然都是意外死亡风皿,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)匠璧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)桐款,“玉大人,你說(shuō)我怎么就攤上這事患朱÷沉牛” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)冰沙。 經(jīng)常有香客問(wèn)我侨艾,道長(zhǎng),這世上最難降的妖魔是什么拓挥? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任唠梨,我火速辦了婚禮,結(jié)果婚禮上侥啤,老公的妹妹穿的比我還像新娘当叭。我一直安慰自己,他們只是感情好盖灸,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布蚁鳖。 她就那樣靜靜地躺著,像睡著了一般赁炎。 火紅的嫁衣襯著肌膚如雪醉箕。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,031評(píng)論 1 285
  • 那天徙垫,我揣著相機(jī)與錄音讥裤,去河邊找鬼。 笑死姻报,一個(gè)胖子當(dāng)著我的面吹牛己英,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播吴旋,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼损肛,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了邮府?” 一聲冷哼從身側(cè)響起荧关,我...
    開(kāi)封第一講書(shū)人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎褂傀,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體加勤,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡仙辟,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了鳄梅。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片叠国。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖戴尸,靈堂內(nèi)的尸體忽然破棺而出粟焊,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布项棠,位于F島的核電站悲雳,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏香追。R本人自食惡果不足惜合瓢,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望透典。 院中可真熱鬧晴楔,春花似錦、人聲如沸峭咒。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)凑队。三九已至钙皮,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間顽决,已是汗流浹背短条。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工导饲, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留摘昌,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓晶伦,卻偏偏與公主長(zhǎng)得像赋访,于是被迫代替她去往敵國(guó)和親可都。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理蚓耽,服務(wù)發(fā)現(xiàn)渠牲,斷路器,智...
    卡卡羅2017閱讀 134,599評(píng)論 18 139
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,504評(píng)論 25 707
  • ¥開(kāi)啟¥ 【iAPP實(shí)現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開(kāi)一個(gè)線程步悠,因...
    小菜c閱讀 6,358評(píng)論 0 17
  • 目標(biāo):百分之九十以上的分?jǐn)?shù) 形同虛設(shè) 不如不寫(xiě) 中心詞:日常 你所期待的是什么呢 你所局限的也不知道吧 你還在思考...
    良辰美LiangChen閱讀 219評(píng)論 0 0
  • JVM隨筆-垃圾回收 感覺(jué)JVM就是記的比較多签杈,明白了概念就記。想明白細(xì)節(jié)原理鼎兽,怕是要看源碼(c/c++編寫(xiě)的) ...
    eqgao閱讀 299評(píng)論 4 1