使用ACR及MIUI自带通话录音实现通话录音读取及上传

news/2024/11/29 5:41:58/

虽然在Android5.0之前在AudioRecord开放给第三方的初始化方法中VOICE_CALL音频源是可以使用的,但是在厂商的适配过程中很多还是不能用,因此在低版本中一直是通过AudioRecord读取MIC录音源实现。

很多厂商在做系统优化时,使用MIC仍然无法通话录音,所以要完美实现可以通过读取其他软件甚至是使用系统自带的拨号软件进行全局通话录音后再读取上传。

首先对几种录音方案进行分析:

1.软件集成录音:

一般是使用AudioRecord读取MIC或者VOICE_CALL音频源进行录音

缺点:
  • 受安卓版本影响较大
  • 需要保证软件正常运行
优点:
  • MP3格式,1分钟60KB

2.ACR

ACR时谷歌商店最好的通话录音软件,在低版本中它也是使用以上方式录音,在大部分Android5.0+手机上仍能录音的方式不得而知

缺点:
  • 受安卓版本影响较大
  • 需要附加安装应用
  • 需要保证软件在通话时正常运行
  • 无法直接录制MP3格式音频文件大,1分钟200KB
  • 无法剪切拨号时未接通的空白音
  • 需要间接读取录音文件
优点:
  • 在某些高版本可用

3.MIUI拨号自带录音

系统自带,只需要打开全局录音开发开关即可

缺点:
  • 需要打开全局录音开关
  • 需要销售拨打电话时不关闭录音
  • 需要间接读取录音文件
优点:
  • 所有MIUI手机都可用
  • mp3格式,1分钟60KB
  • 系统应用,不受CRM是否运行影响

针对以上分析,对三种方案都做了集成,对使用第三方录音的代码分享如下:

ACR录音读取分析:

ACR录音文件存放于sdcard/ACRCalls目录,文件格式如下:

1d20170330120101p10010.m4a

录音类型d录音开始时间p录音号码.录音文件格式

相应正则:

^(\d)d(\d{14})p(\d*)\.\w+$

上代码:

/*** 查找由ACR录音软件录制的通话录音,并继续流程** @param isOutCall   是否为呼出电话* @param phoneNumber 通话对方号码* @param startTime   开始时间* @param stopTime    结束时间* @return 查找到的录音文件*/
private static File findAcrRecordFile(boolean isOutCall, String phoneNumber, long startTime, long stopTime) {String callType = isOutCall ? "1" : "0";//时间容错范围startTime = startTime - 1000;stopTime = stopTime + 1000;//acr默认录音目录File fileDir = new File(Environment.getExternalStorageDirectory(), "ACRCalls");if (fileDir.exists() && fileDir.isDirectory()) {//筛选出指定号码,指定时间段内的录音File[] records = fileDir.listFiles();if (records.length <= 0) {return null;}//先判断最后一个文件是否符合File acrRecordFile = records[records.length - 1];if (checkACRRecordFile(acrRecordFile, callType, phoneNumber, startTime, stopTime)) {return acrRecordFile;}//不符合时遍历寻找for (int i = 0; i < records.length; i++) {acrRecordFile = records[i];if (checkACRRecordFile(acrRecordFile, callType, phoneNumber, startTime, stopTime)) {return acrRecordFile;}}}LogUtils.w(TAG, "未找到ACR录音文件");return null;
}private static boolean checkACRRecordFile(File srcFile, String callType, String phoneNumber, long startTime, long stopTime) {if (srcFile == null || !srcFile.isFile()) {return false;}//文件时间提取格式化SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss", Locale.CHINA);//判断文件是否为指定文件String name = srcFile.getName();String recordType = name.replaceAll("^(\\d)d(\\d{14})p(\\d*)\\.\\w+$", "$1");//通话类型(0:呼入;1:呼出)String recordDate = name.replaceAll("^(\\d)d(\\d{14})p(\\d*)\\.\\w+$", "$2");//录音开始时间String recordPhone = name.replaceAll("^(\\d)d(\\d{14})p(\\d*)\\.\\w+$", "$3");//录音号码long recordTime = sdf.parse(recordDate, new ParsePosition(0)).getTime();return (callType.equals(recordType) && recordTime > startTime && recordTime < stopTime && phoneNumber.equals(recordPhone));
}

读取MIUI通话录音

录音文件路径:sdcard/MIUI/sound_recorder/call_rec

通话录音@中国联通(10010)_20170330120101.mp3

相应正则:

^通话录音@[^()]+\((\d+)\)_(\d{14})\.mp3$

代码:

/*** 查找由MIUI自带录音软件录制的通话录音,并继续流程** @param phoneNumber 通话对方号码* @param startTime   开始时间* @param stopTime    结束时间* @return 查找到的录音文件*/
private static File findMIUIRecordFile(String phoneNumber, long startTime, long stopTime) {//时间容错范围startTime = startTime - 1000;stopTime = stopTime + 1000;//acr默认录音目录File fileDir = new File(Environment.getExternalStorageDirectory(), "MIUI/sound_recorder/call_rec");//筛选出指定号码,指定时间段内的录音if (fileDir.exists() && fileDir.isDirectory()) {File[] records = fileDir.listFiles();LogUtils.e(TAG, records.toString());if (records.length <= 0) {return null;}//先判断最后一个文件是否符合File acrRecordFile = records[records.length - 1];if (checkMIUIRecordFile(acrRecordFile, phoneNumber, startTime, stopTime)) {return acrRecordFile;}//不符合时遍历寻找for (int i = 0; i < records.length; i++) {acrRecordFile = records[i];if (checkMIUIRecordFile(acrRecordFile, phoneNumber, startTime, stopTime)) {return acrRecordFile;}}}LogUtils.w(TAG, "未找到MIUI录音文件");return null;
}private static boolean checkMIUIRecordFile(File srcFile, String phoneNumber, long startTime, long stopTime) {if (srcFile == null || !srcFile.isFile()) {return false;}//文件时间提取格式化SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss", Locale.CHINA);String name = srcFile.getName();String recordDate = "";String recordPhone = "";if (name.matches("^通话录音@[^()]+\\((\\d+)\\)_(\\d{14})\\.mp3$")) {recordDate = name.replaceAll("^通话录音@[^()]+\\((\\d+)\\)_(\\d{14})\\.mp3$", "$2");//录音开始时间recordPhone = name.replaceAll("^通话录音@[^()]+\\((\\d+)\\)_(\\d{14})\\.mp3$", "$1");//录音号码} else if (name.matches("^通话录音@(\\d+)_(\\d{14})\\.mp3$")) {recordDate = name.replaceAll("^通话录音@(\\d+)_(\\d{14})\\.mp3$", "$2");//录音开始时间recordPhone = name.replaceAll("^通话录音@(\\d+)_(\\d{14})\\.mp3$", "$1");//录音号码}long recordTime = sdf.parse(recordDate, new ParsePosition(0)).getTime();return recordTime > startTime && recordTime < stopTime && phoneNumber.equals(recordPhone);
}

http://www.ppmy.cn/news/429204.html

相关文章

Android 通话录音功能

通话录音功能因为涉及隐私问题&#xff0c;Android 6.0上就移除官方的通话录音接口&#xff0c;只能通过其他方式去获取调用。 录音时需要设置音频类型&#xff0c;系统中定义以下几种 &#xff08;MediaRecorder.AudioSource&#xff09; CAMCORDER 录音来源于同方向的相机麦…

android实现通话录音获取上传实现过程记录。

项目里提了一个需求&#xff0c;需要通话录音功能(录制双方的声音)&#xff0c;并上传到后台。(软件是内部人员工作使用不涉及个人隐私) 首先想到的肯定是用APP来进行录音&#xff0c;可控性比较高&#xff0c;测试了android自带的MediaRecorder与AudioRecord结果发现都只能录…

uniapp 移动端通话录音上传

记录一下近半个月的一个项目解决思路 需求是这样的 1&#xff0c;通话双向录音 2&#xff0c;监听移动端通话状态 3&#xff0c;挂断后上传通话录音到后端进行统计 先说下第一点 通话双向录音&#xff0c;这个在android 6之前还有办法实现&#xff0c;但是现在基本都是单向的&a…

通话录音

当我拿到Demo时候&#xff0c;就觉得是个很简单的功能。然而问题就在测试时候完全暴露出来了&#xff0c;不同手机不同机型由于厂家修改系统而导致的一堆奇葩问题接踵而至&#xff0c;手机通话状态监听不到、通话状态接收多次、通话状态混乱等问题。 下面就是根据测试的手机机…

分享!!前端也需要了解的一些技术!!

目录 1、临时路径共享使用 2、关闭指定端口号的进程 1、临时路径共享使用 场景&#xff1a;自己开发中的pc、移动端、app等&#xff0c;由于还在开发中&#xff0c;没有上线&#xff0c;此时有的人需要暂时使用它么&#xff0c;那么就可以创建一个临时路径&#xff0c;共享给…

【Docker】技术架构演进

基本概念 应用&#xff08;Application&#xff09; / 系统&#xff08;System&#xff09; ​ 为了完成一整套服务的一个程序或者一组相互配合的程序群。生活例子类比&#xff1a;为了完成一项任务&#xff0c;而搭建的由一个人或者一群相互配的人组成的团队。 模块&#xff0…

物理内存与虚拟内存--问答

1&#xff0e;请简述Linux内核在理想情况下页面分配器&#xff08;page allocator&#xff09;是如何分配出连续物理页面的。 2&#xff0e;在页面分配器中&#xff0c;如何从分配掩码&#xff08;gfp_mask&#xff09;中确定可以从哪些zone中分配内存&#xff1f; 3&#xff0…

台式计算机怎么加一个硬盘,台式电脑硬盘怎么多安装一个?电脑安装多加一块硬盘的方法...

台式电脑硬盘运行久了会储存很多数据资料&#xff0c;时间久了&#xff0c;硬盘空间就不够用了&#xff0c;如果重新换电脑要花费很多资金。其实我们可以给电脑多加一个硬盘&#xff0c;增加硬盘空间&#xff0c;加快系统运行速度。那么台式电脑硬盘怎么多安装一个&#xff1f;…