通话录音

news/2024/11/29 7:58:45/

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


public class PhoneService extends Service {private static final String SERIAL_NUMBER = "serialNumber";TelephonyManager telephonyManager;String end_time = "";String start_time = "";private PhoneResponseReceiver phoneOperationBrocast;private int lastState = -1;@Overridepublic IBinder onBind(Intent intent) {// TODO Auto-generated method stubreturn null;}@Overridepublic void onCreate() {super.onCreate();isExption = false;System.out.println("MODEL:" + android.os.Build.MODEL);//返回一个电话对象telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);if (android.os.Build.MODEL.equals("GT-N7102")) {//三星手机IntentFilter phoneFilter = new IntentFilter();phoneFilter.addAction("android.intent.action.PHONE_STATE");phoneFilter.addAction(Intent.ACTION_NEW_OUTGOING_CALL);phoneOperationBrocast = new PhoneResponseReceiver();registerReceiver(phoneOperationBrocast, phoneFilter);}else {callin();}System.out.println("创建服务---------------------");}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {System.out.println("onStartCommand---------------------");if (null != intent) {System.out.println("onStartCommand---------1------------");incomeNumber = intent.getStringExtra("tel");System.out.println("去电号码" + incomeNumber);}return super.onStartCommand(intent, flags, startId);}/*** 电话状态的监听* 1,检测是否为客户电话,是的话需要记录一次客户电话记录*/public class PhoneResponseReceiver extends BroadcastReceiver {/*** TODO MGC 重写,避免逻辑错误*/public void onReceive(Context context, Intent intent) {if (intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)) {//拨打电话
//                callout(context, intent);} else {//接电话// TODO: 7/8/16 在电话没有接听起来就变成IDE的话,就说明是客户挂了电话需要记录到数据库缓存中callin();}}}private String incomeNumber = ""; // 来电号码private MediaRecorder mediaRecorder;   //录制音频private File file;private boolean isExption;private void callin() {telephonyManager.listen(new PhoneStateListener() {@Overridepublic void onCallStateChanged(int state, String incomingNumber) {try {System.out.println(">>>>>>CallState>>>>>>>>" + state);  //输出 的是0 和 2switch (state) {case TelephonyManager.CALL_STATE_RINGING: // 来电System.out.println(">>>>>>来电>>>>>>>>" + state);
//                        this.incomeNumber = incomingNumber;break;case TelephonyManager.CALL_STATE_OFFHOOK: // 接通电话System.out.println(">>>>>>接电话>>>>>>>>" + state);//TODO 防止多次触发if (TelephonyManager.CALL_STATE_OFFHOOK == lastState) {return;}System.out.println(">>>>>>lastState>>>>>>>>" + lastState);//TODO 正常流程if (lastState == -1 || isExption) {//获取开始通话时间Date date1 = new Date();SimpleDateFormat format1 = new SimpleDateFormat("yyyyMMddHHmmss");start_time = format1.format(date1);//+ System.currentTimeMillis()file = new File(Environment.getExternalStorageDirectory().toString() + "/" +UserManager.getInstance().getUser().getId() + "_" + incomeNumber + "_" + start_time+ ".mp3");System.out.println(">>>>>>接通>>>>>>>>" + state);System.out.println("MODEL:" + android.os.Build.MODEL);mediaRecorder = new MediaRecorder();mediaRecorder.reset();
//                         mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//获得声音数据源(下麦克风)if (android.os.Build.MODEL.equals("Redmi Note 2")) {//小米手机System.out.println("MediaRecorder.AudioSource.MIC");mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//这个设置就是获取双向声音} else {System.out.println("MediaRecorder.AudioSource.VOICE_CALL");mediaRecorder.setAudioSource(MediaRecorder.AudioSource.VOICE_CALL);//这个设置就是获取双向声音}mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); // 按3gp格式输出THREE_GPPmediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);mediaRecorder.setOutputFile(file.getAbsolutePath()); // 输出文件mediaRecorder.prepare(); // 准备mediaRecorder.start();} else {//TODO 异常流程isExption = true;}break;case TelephonyManager.CALL_STATE_IDLE: // 挂掉电话System.out.println(">>>>>>挂电话>>>>>>>>" + state);//TODO 防止多次触发if (TelephonyManager.CALL_STATE_IDLE == lastState) {return;}//TODO 异常标记if (mediaRecorder == null) {isExption = true;return;}//TODO 异常流程if (lastState == -1) {} else {//TODO 正常流程//获取结束通话时间if (mediaRecorder != null) {Date date2 = new Date();SimpleDateFormat format2 = new SimpleDateFormat("yyyyMMddHHmmss");end_time = format2.format(date2);System.out.println(">>>>"+ Environment.getExternalStorageDirectory());mediaRecorder.stop();mediaRecorder.release();   //  释放资源mediaRecorder = null;//当挂断电话之后,取消 电话监听telephonyManager.listen(this, PhoneStateListener.LISTEN_NONE);new Handler().postDelayed(new Runnable() {@Overridepublic void run() {//TODO 获取通话时长String duration = CallLogUtil.getCallLength(PhoneService.this);if (Integer.valueOf(duration) <= 1) {stopSelf();System.out.println("stopSelf----未接通-----------------");return;}//TODO 获取流水号int serialNum = ShareManager.getInt(PhoneService.this, SERIAL_NUMBER);serialNum++;File reFile = new File(Environment.getExternalStorageDirectory().toString() + "/" +UserManager.getInstance().getUser().getId() + "_" + incomeNumber + "_" + start_time+ "_" + end_time + "_" + String.format("%06d", serialNum) + ".mp3");//修改名字file.renameTo(reFile);MobileManagerApplication.file = reFile;//TODO 删除原来的文件file.delete();//TODO 录音文件保存成功,流水号+1保存ShareManager.setInt(PhoneService.this, SERIAL_NUMBER, serialNum);//TODO 录音记录保存到数据库中saveRecordFiletoDB(duration, serialNum);//TODO 广播通知上传文件Intent intent = new Intent("com.yintai.mobmanager.FINISHCALL");intent.putExtra("isFinishCall", true);sendBroadcast(intent);System.out.println("发送广播");//TODO 关闭通话录音服务stopSelf();System.out.println("stopSelf---------------------");}}, 3000);}isExption = false;}break;}} catch (IllegalStateException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();}lastState = state;}}, PhoneStateListener.LISTEN_CALL_STATE);}/*** TODO 记录录音文件到数据库中*/private void saveRecordFiletoDB(String duration, int serialNum) {if (Integer.valueOf(duration) <= 1) {return;}Record record = new Record();record.setCall_start(start_time);record.setCall_end(end_time);record.setCall_length(duration);record.setPhone(incomeNumber);record.setNumber(String.format("%06d", serialNum));record.setFileName(MobileManagerApplication.file.getName());record.setAbsolutePath(MobileManagerApplication.file.getAbsolutePath());record.setUploadFlag(0);try {DbUtils.create(PhoneService.this).save(record);
//            DatabaseManager.getInstance().getDb().save(record);} catch (DbException e) {e.printStackTrace();}}@Overridepublic void onDestroy() {if (null != phoneOperationBrocast) {unregisterReceiver(phoneOperationBrocast);phoneOperationBrocast = null;}telephonyManager = null;file = null;incomeNumber = "";mediaRecorder = null;super.onDestroy();}}

最后备注下,需要在AndroidManifest.xml文件中添加权限

    <!-- 获取读取通讯录记录的权限 --><uses-permission android:name="android.permission.READ_CALL_LOG" /><uses-permission android:name="android.permission.READ_CONTACTS" /><uses-permission android:name="android.permission.WRITE_CONTACTS" /><uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><uses-permission android:name="android.permission.CALL_PHONE"/><uses-permission android:name="android.permission.READ_PHONE_STATE"/><!-- 刻入声音权限 --><uses-permission android:name="android.permission.RECORD_AUDIO" /><uses-permission android:name="android.permission.SEND_SMS" /><!-- 添加权限 --><uses-permission android:name="android.permission.RECEIVE_SMS" /><uses-permission android:name="android.permission.READ_SMS" /><!-- 在SDCard写入数据权限 --><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /><!-- 在SDCard中创建与删除文件权限 --><uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /><uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /><uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /><!-- 监听电话状态权限 --><uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" /><uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /><uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /><uses-permission android:name="android.permission.CHANGE_CONFIGURATION" /><uses-permission android:name="android.permission.WAKE_LOCK" /><uses-permission android:name="android.permission.CAMERA" /><uses-permission android:name="android.permission.WRITE_SETTINGS" /><uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /><!-- SD卡读取权限,用户写入离线定位数据 --><uses-permission android:name="android.permission.read_logs" /><uses-permission android:name="android.permission.GET_TASKS" /><!-- 拨打电话的权限 --><uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" /><uses-permission android:name="android.permission.BLUETOOTH" /><uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /><uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /><uses-permission android:name="android.permission.DISABLE_KEYGUARD" /><uses-permission android:name="android.permission.VIBRATE" /><uses-permission android:name="android.permission.WRITE_OWNER_DATA" /><uses-permission android:name="android.permission.BROADCAST_STICKY" /><!--录音--><uses-permission android:name="android.permission.CAPTURE_AUDIO_OUTPUT" />

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

相关文章

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

目录 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;…

安装完固态硬盘后计算机里没显示,安装了双硬盘电脑却不显示新硬盘怎么办

安装了双硬盘电脑却不显示新硬盘怎么办 我们在为电脑安装了一个新的硬盘之后&#xff0c;发现并没有显示出来。那么安装了双硬盘电脑却不显示新硬盘怎么办呢?下面就让jy135小编来告诉大家吧&#xff0c;欢迎阅读。 1、在“我的电脑”上面单击右键&#xff0c;选择“属性”&…

计算机使用中硬盘突然不见了,电脑硬盘突然消失不见

大家好&#xff0c;我是时间财富网智能客服时间君&#xff0c;上述问题将由我为大家进行解答。 电脑硬盘突然消失不见问题原因分析如下&#xff1a; 1、IDE电缆连接口接触不良、断裂&#xff1b;检查IDE电缆线接口&#xff0c;重新插好&#xff0c;若断裂则更换过。 2、IDE接口…

计算机如何新增硬盘,电脑新增加一块硬盘安装并使用的教程

电脑新增加一块硬盘怎么安装使用&#xff1f;现在配置电脑主机&#xff0c;在存储这方面&#xff0c;主流推荐都会使用SSD硬盘&#xff0c;因为读写速度快&#xff0c;在SSD系统上安装系统&#xff0c;开机只需要10多秒&#xff0c;很在程序上提高了体验&#xff0c;但SSD成本较…

计算机硬盘如何安装系统,电脑硬盘怎么装系统

描述 首先自然是安装新硬盘&#xff0c;我们把旧的硬盘拆下来&#xff0c;然后把新的硬盘安装上去&#xff0c;安装的时候不要使用蛮力&#xff0c;以免破坏硬盘的针头&#xff0c;导致硬盘不能使用。如果你对安装硬盘不是很在行的话&#xff0c;可以求助其他人帮忙安装&#x…