Android 录音工具AudioRecordUtil

一、录音工具类

import android.content.Context;
import android.media.MediaRecorder;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.os.StatFs;
import android.util.Log;
import android.widget.Toast;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.Timer;
import java.util.TimerTask;

/**
 * CreateTime 2017/10/13 22:25
 * Author LiuShiHua
 * Description:录音
 * <p>
 * 1.判断没有存储卡——不录音
 * 2.判断存储卡容量小于50M——不录音
 * 3.默认小于1秒不保存
 * <p>
 * 自动保存
 */

public class RecordAudioUtil {

    private boolean highQuality = true; // 高质量为true, 低质量为false

    private MediaRecorder mMediaRecorder;
    private boolean isRunning = false;
    private File saveFile;
    private long endTimeLong;
    private long startTimeLong;
    private FileInputStream fis;
    private FileOutputStream fos;
    private Timer timer;
    private Handler handler;
    private final int HAND_VOICE_HIGH = 0x10;

    /**
     * 开始录音
     *
     * @return 开始成功/失败
     */
    public boolean startRecord(Context context, String savePath, Handler handler) {
        this.handler = handler;
        if (isRunning) {
            return false;
        }
        if (!hasSdcard()) {
            Toast.makeText(context, "请先插入SD卡(存储卡)", Toast.LENGTH_SHORT).show();
            return false;
        }
        if (!isSDCanUseSize50M()) {
            Toast.makeText(context, "内存已经不足50M了,请先清理手机空间", Toast.LENGTH_SHORT).show();
        }
        saveFile = new File(savePath);
        if (!saveFile.exists()) {
            saveFile.getParentFile().mkdirs();
            try {
                saveFile.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
                Toast.makeText(context, "文件创建失败", Toast.LENGTH_SHORT).show();
                return false;
            }
        }
        mMediaRecorder = new MediaRecorder();
        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); // 在setOutputFormat之前
        mMediaRecorder.setOutputFile(saveFile.getAbsolutePath());//设置输出路径【会直接保存】

        mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
        mMediaRecorder.setAudioSamplingRate(highQuality ? 44100 : 22050);
        mMediaRecorder.setAudioEncodingBitRate(16000);
        mMediaRecorder.setAudioChannels(1);
        mMediaRecorder.setAudioSamplingRate(8000); // 96 kHz is a very high sample rate, and is not guaranteed to be supported. I suggest that you try a common sample rate <= 48 kHz (e.g. 48000, 44100, 22050, 16000, 8000).
        mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
        try {
            startTimeLong = System.currentTimeMillis();
            mMediaRecorder.prepare();
            mMediaRecorder.start();
            startVoiceTimer();
        } catch (Exception e) {//未授权也会在这里抛出异常
            e.printStackTrace();
            Log.d("------------>录音", "mMediaRecorder报错:" + e.getMessage());
            isRunning = false;
            return false;
        }
        isRunning = true;
        return true;
    }

    //获取声音分贝的timer
    private void startVoiceTimer() {
        timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                if (handler != null) {
                    if (isRunning) {
                        Message message = new Message();
                        message.what = HAND_VOICE_HIGH;
                        message.arg1 = mMediaRecorder.getMaxAmplitude();
                        handler.sendMessage(message);
                    } else {
                        this.cancel();
                    }
                }
            }
        }, 100, 100);
    }

    //暂停录音
    public void pause() {

    }

    /**
     * 停止录音
     * 【不对外提供是否保存的功能——始终保存】
     * isNeedSave 是否保存录音文件, true表示保存, false表示不保存
     */
    public void stopRecord() {
        boolean isNeedSave = true;
        if (!isRunning) {
            return;
        }
        if (mMediaRecorder == null) return;
        if(timer!=null){
            timer.cancel();
        }
        endTimeLong = System.currentTimeMillis();

        /** 开始时间与结束时间小于一秒则不保存 */
        if ((endTimeLong - startTimeLong) < 1000) {
            mMediaRecorder.stop();
            mMediaRecorder.release();
            mMediaRecorder = null;
            isRunning = false;
            if (saveFile.exists()) {
                saveFile.delete();
            }
            return;
        }

        mMediaRecorder.stop();
        mMediaRecorder.release();
        mMediaRecorder = null;
        isRunning = false;
        if (isNeedSave) { // 保存文件【文件已经保存】
//            try {
//                fis = new FileInputStream(saveFile);
//                byte[] oldByte = new byte[(int) saveFile.length()];
//                fis.read(oldByte); // 读取
//                // 加密
//                fos = new FileOutputStream(saveFile);
//                fos.write(oldByte);
//            } catch (FileNotFoundException e) {
//                e.printStackTrace();
//            } catch (IOException e) {
//                e.printStackTrace();
//            } catch (Exception e) {
//                e.printStackTrace();
//            } finally {
//                try {
//                    fis.close();
//                    fos.close();
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            }
        } else { // 不保存文件
            if (saveFile.exists()) {
                saveFile.delete();
            }
        }
    }

    /**
     * 检查设备是否存在SDCard的工具方法
     */
    public static boolean hasSdcard() {
        String state = Environment.getExternalStorageState();
        if (state.equals(Environment.MEDIA_MOUNTED)) {
            // 有存储的SDCard
            return true;
        } else {
            return false;
        }
    }

    /**
     * 获得sd卡剩余容量是否有50M,即可用大小
     *
     * @return
     */
    public static boolean isSDCanUseSize50M() {
        if (!hasSdcard()) {
            return false;
        }
        File path = Environment.getExternalStorageDirectory();
        StatFs sf = new StatFs(path.getPath());
        long size = sf.getBlockSize();//SD卡的单位大小
        long total = sf.getBlockCount();//总数量
        long available = sf.getAvailableBlocks();//可使用的数量
        DecimalFormat df = new DecimalFormat();
        df.setGroupingSize(3);//每3位分为一组
//        //总容量
//        String totalSize = (size * total) / 1024 >= 1024 ? df.format(((size * total) / 1024) / 1024) + "MB" : df.format((size * total) / 1024) + "KB";
//        //未使用量
//        String avalilable = (size * available) / 1024 >= 1024 ? df.format(((size * available) / 1024) / 1024) + "MB" : df.format((size * available) / 1024) + "KB";
//        //已使用量
//        String usedSize = size * (total - available) / 1024 >= 1024 ? df.format(((size * (total - available)) / 1024) / 1024) + "MB" : df.format(size * (total - available) / 1024) + "KB";
        if (size * available / 1024 / 1024 < 50) {
            return false;
        }
        return true;
    }
}

二、调用方式(Activity中添加以下代码)

private RecordAudioUtil audioUtil = new RecordAudioUtil();

    //声音大小
    private final int HAND_VOICE_HIGH = 0x10;

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);

            switch (msg.what) {
                case 0:
                    secoundsT.setText(times + "秒");
                    break;
                case 1:
                    presenter.stopRecord();
                    playType = 2;
                    secoundsT.setText(times + "秒");
                    playImg.setBackgroundResource(R.mipmap.record_a_play);
                    sureT.setTextColor(Color.parseColor("#00a9a5"));
                    recordAgain.setTextColor(Color.parseColor("#00a9a5"));
                    sureT.setEnabled(true);
                    recordAgain.setEnabled(true);
                    break;
                case HAND_VOICE_HIGH://声音的高低
                    int voiceh = msg.arg1;
                    double ratio = (double) voiceh / 100;
                    double db = 0;// 分贝
                    //默认的最大音量是100,可以修改,但其实默认的,在测试过程中就有不错的表现
                    //你可以传自定义的数字进去,但需要在一定的范围内,比如0-200,就需要在xml文件中配置maxVolume
                    //同时,也可以配置灵敏度sensibility
                    if (ratio > 1)
                        db = 20 * Math.log10(ratio);
                    //只要有一个线程,不断调用这个方法,就可以使波形变化
                    //主要,这个方法必须在ui线程中调用
                    voiceLine.setVolume((int) (db));
                    break;
            }
        }
    };

//开始录音
    public String startRecord(Handler handler) {
        String path = PathUtil.getAudioPath();//传入保存路径
        boolean isStartOk = audioUtil.startRecord(context, path, handler);
        if (isStartOk) return path;
        return null;
    }
//停止录音
    public void stopRecord() {
        audioUtil.stopRecord();
    }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值