VoiceManager的封装

这是一个录音和播放封装,我们有一个封装类:
VoiceManager.class,我们播放音乐,我们的view也需要对应的变化,音乐来控制我们ui控件的变化也就是我们的时间来控制我们的ui变化,所以我们需要的一个计算时间的工具类,也就是我们的VoiceTimeUtils.class

1.播放录音的工具类--- MediaPlayer
(注意,我们可以看到在准备播放的方法里面每一个返回的是布尔值,当我们的播放方法执行了的时候就会放回true,没有执行的时候,放回的是false,这个点子很好,值得我们记住!)

  • 准备工作:
  /**
     * 播放录音准备工作
     */
    private boolean prepareMedia(MediaPlayer mp,String file){
        boolean result = false;
        try {
            mp.setDataSource(file);
            mp.prepare();
            result = true;
        } catch (Exception e) {
        }

        return result;
    }

 /**
     * 播放录音开始
     * @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;
    }

此外我们开启一个线程来检测我们的录音声音频率的大小:
(可以看到我们这个类中定义了一个方法叫exit他里面控制一个布尔值为false,然后在我们的run方法中用while循环来检测我们exit方法里面布尔值是否为false,如果为false就停止录音,否则就一直录音)

  /**
     * 监听录音声音频率大小
     */
     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
(可以看到我们的录音准备方法里面,回调的是我们的文件存放地址,这个就很机智了,还有就是我们的录音准备工作要设置的配置,我们简单缩写一下就是,ASM,AEA,UFR,还有一个就是设置我们的地址)

  • 准备工作:
1. 判断我们的录音的存放地址是否是正确:

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

/**
    * 录音准备工作 ,开始录音
    *
    * @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;
   }

第二部分 接口

 /**
     * 录音回调监听
     */
    public interface VoiceRecordCallBack{
        //录音中
        void recDoing(long time,String strTime);
        //录音中的声音频率等级;
        void recVoiceGrade(int grade);
        //录音开始
        void recStart(boolean init);
        //录音暂停
        void recPause(String str);
        //录音结束
        void recFinish(long lenth,String strLenth,String path);
    }

 /**
     * 播放录音回调监听
     */
    public interface VoicePlayCallBack{
        /**
         * 音频长度
         * 指定的某个时间段,以秒为单位
         */
        void voiceTotalLenth(long time,String strTime);
        /**
         * 播放中
         * 指定的某个时间段,以秒为单位
         */
        void playDoing (long time,String strTime);
        //播放暂停
        void playPause();
        //播放开始
        void playStart();
        //播放结束
        void  playFinish();
    }

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

3.第三部分 具体代码

上面我们完成了我们的准备工作,现在开始我们的具体代码:

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;

    // 多媒体例如声音的状态
    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;
    }

    /**
     * 播放器结束监听
     */
    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);
                            //回调录音时间
                            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);
                            //回调播放进度
                            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***************************/
    /**
     * 设置录音监听
     * @param callback
     */
      public void setVoiceRecordListener(VoiceRecordCallBack callback){
         this.voiceRecordCallBack = callback;
     }

    /**
     * 开始录音(外部调用)
     * @param filePath
     */
     public void startVoiceRecord(String filePath){
         if (!isSDCardAvailable()) return ;
         this.recordFilePath = filePath;
         startVoiceRecord(true);
     }

    /**
     * 继续或暂停录音
     */
    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, "时间过短", Toast.LENGTH_SHORT).show();
             } else {
                 File file = getOutputVoiceFile(mRecList);
                 if (file != null && file.length() > 0) {
                     cleanFieArrayList(mRecList);
                     //TODO 这里可以返回数据 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();
         }
     }

    /**
     * 开始录音(内部调用)
     * @param init
     */
     private void startVoiceRecord(boolean init){
         if (!isSDCardAvailable()) return;
         if (init) {
             mRecTimeSum = 0;
             cleanFieArrayList(mRecList);
         }
         //录音前停止播放回调
         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) {
             //开始录音回调
             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);
         }

     }

    /**
     * 监听录音声音频率大小
     */
     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);

         // 创建音频文件,合并的文件放这里
         File resFile = new File(recDirFile, mMinute1 + ".amr");
         FileOutputStream fileOutputStream = null;
         try {
             fileOutputStream = new FileOutputStream(resFile);
         } catch (IOException e) {
         }
         // list里面为暂停录音 所产生的 几段录音文件的名字,中间几段文件的减去前面的6个字节头文件
         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()];
                 // 文件长度
                 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();
             }
         }
         // 结束后关闭流
         try {
             fileOutputStream.close();
         } catch (IOException e) {
             e.printStackTrace();
         }

         return resFile;

     }

    /**
     * 清空暂停录音所产生的几段录音文件
     * @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监听
     * @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);
                     //播放进度
                     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);
                     }
                 }
             });
         }

     }

    /**
     * 开始播放(外部调用)
     * @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);
         }

     }

    /**
     * 开始播放(内部调用)
     * @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;
                 //总时间长度
                 long totalTime = mMediaPlayer.getDuration() / 1000;
                 VoiceTimeUtils ts = VoiceTimeUtils.timeSpanSecond(totalTime);
                 String voiceLength = String.format("%02d:%02d:%02d",
                         ts.mSpanHour, ts.mSpanMinute, ts.mSpanSecond);
                 //播放进度回调
                 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("播放出错了", e.getMessage());
         }

     }

    /**
     * 继续暂停
     */
    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***************************/

    /**
     * 播放录音准备工作
     */
    private boolean prepareMedia(MediaPlayer mp,String file){
        boolean result = false;
        try {
            mp.setDataSource(file);
            mp.prepare();
            result = true;
        } catch (Exception e) {
        }

        return result;
    }

    /**
     * 播放录音开始
     * @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 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;

    }

    /**
     * 录音准备工作 ,开始录音
     *
     * @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;
    }

    /**
     * 录音回调监听
     */
    public interface VoiceRecordCallBack{
        //录音中
        void recDoing(long time,String strTime);
        //录音中的声音频率等级;
        void recVoiceGrade(int grade);
        //录音开始
        void recStart(boolean init);
        //录音暂停
        void recPause(String str);
        //录音结束
        void recFinish(long lenth,String strLenth,String path);
    }
    /**
     * 播放录音回调监听
     */
    public interface VoicePlayCallBack{
        /**
         * 音频长度
         * 指定的某个时间段,以秒为单位
         */
        void voiceTotalLenth(long time,String strTime);
        /**
         * 播放中
         * 指定的某个时间段,以秒为单位
         */
        void playDoing (long time,String strTime);
        //播放暂停
        void playPause();
        //播放开始
        void playStart();
        //播放结束
        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;
    }
}

本项目的url地址:
https://github.com/jaydenxiao2016/VoiceManager/blob/master/app/src/main/java/com/jaydenxiao/voicemanager/RecordVoiceButton.java

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,580评论 18 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,384评论 25 707
  • ¥开启¥ 【iAPP实现进入界面执行逐一显】 〖2017-08-25 15:22:14〗 《//首先开一个线程,因...
    小菜c阅读 6,345评论 0 17
  • 目标:百分之九十以上的分数 形同虚设 不如不写 中心词:日常 你所期待的是什么呢 你所局限的也不知道吧 你还在思考...
    良辰美LiangChen阅读 219评论 0 0
  • JVM随笔-垃圾回收 感觉JVM就是记的比较多,明白了概念就记。想明白细节原理,怕是要看源码(c/c++编写的) ...
    eqgao阅读 299评论 4 1