每一个看似简单的功能背后,都是攻城狮们用汗水填起的坑,尤其在这么热的天。
最近又邂逅了Android的录音模块,由于是前同事留下的代码,bug改得宝宝真是欲仙欲死。首先看下原始的实现:
其中RecorderHelp中封装了MediaRecorder,录音这种耗时操作放在了AsyncTask中进行。其实并说不上这种设计有什么缺点,但在使用的过程确实虐心,下边是自己的实现。
一个比较恶心的问题,如何在开启录音前增加权限检测。在Google原生SDK上,当然可以使用CompatContext.checkSelfPermission来做,但碰到小米华为等手机,这个方法就gg了,无论用户是否禁止了录音权限,都会返回给PERMISSION_GRANTED。没办法,果断google,大概有如下几个方案:
1.try catch MediaRecorder在start的时候,如果没有权限会抛出状态异常,但尝试后发现华为手机是不抛任何异常的,小米会启动失败。
2.预录制一段音频,判断麦克风振幅。但这个方案在小米上貌似是可以的,他妈的华为的又gg了。
3.接着2,华为的虽然靠振幅不能判断,但P7上是不会生成录音文件的,大喜。结果提交后,QA反馈honor上在权限被禁的情况下可以录制1s的文件。。。。要去日几只狗。
后边老大提醒看下微信是如何做的,看了下微信,体验还真不错,但突然想到微信是可以语音转文字的啊,那肯定是用AudioRecorder了。随手Google下AudioRecorder,有哥们给出了如下方案
最近又邂逅了Android的录音模块,由于是前同事留下的代码,bug改得宝宝真是欲仙欲死。首先看下原始的实现:
其中RecorderHelp中封装了MediaRecorder,录音这种耗时操作放在了AsyncTask中进行。其实并说不上这种设计有什么缺点,但在使用的过程确实虐心,下边是自己的实现。
一个比较恶心的问题,如何在开启录音前增加权限检测。在Google原生SDK上,当然可以使用CompatContext.checkSelfPermission来做,但碰到小米华为等手机,这个方法就gg了,无论用户是否禁止了录音权限,都会返回给PERMISSION_GRANTED。没办法,果断google,大概有如下几个方案:
1.try catch MediaRecorder在start的时候,如果没有权限会抛出状态异常,但尝试后发现华为手机是不抛任何异常的,小米会启动失败。
2.预录制一段音频,判断麦克风振幅。但这个方案在小米上貌似是可以的,他妈的华为的又gg了。
3.接着2,华为的虽然靠振幅不能判断,但P7上是不会生成录音文件的,大喜。结果提交后,QA反馈honor上在权限被禁的情况下可以录制1s的文件。。。。要去日几只狗。
后边老大提醒看下微信是如何做的,看了下微信,体验还真不错,但突然想到微信是可以语音转文字的啊,那肯定是用AudioRecorder了。随手Google下AudioRecorder,有哥们给出了如下方案
public static int getRecordState() {
int minBuffer = AudioRecord.getMinBufferSize(44100, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
AudioRecord audioRecord = new AudioRecord(MediaRecorder.AudioSource.DEFAULT, 44100, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, (minBuffer * 100));
short[] point = new short[minBuffer];
int readSize = 0;
try {
audioRecord.startRecording();//检测是否可以进入初始化状态
} catch (Exception e) {
if (audioRecord != null) {
audioRecord.release();
audioRecord = null;
LogUtils.d("CheckAudioPermission", "无法进入录音初始状态");
}
return STATE_NO_PERMISSION;
}
if (audioRecord.getRecordingState() != AudioRecord.RECORDSTATE_RECORDING) {
//6.0以下机型都会返回此状态,故使用时需要判断bulid版本
//检测是否在录音中
if (audioRecord != null) {
audioRecord.stop();
audioRecord.release();
audioRecord = null;
LogUtils.d("CheckAudioPermission", "录音机被占用");
}
return STATE_RECORDING;
} else {
//检测是否可以获取录音结果
readSize = audioRecord.read(point, 0, point.length);
if (readSize <= 0) {
if (audioRecord !