android 解决通话录音时无法返回挂断状态的bug
据了解,安卓6.0开始不再支持通话录音,除非修改系统、系统放开权限、root,这也可以理解,毕竟这涉及到隐私问题,万一我一个亿的银行密码被人窃听了呢?
最近有个定制的系统有个需求--------通话录音,一切就绪后,发现一个BUG,普通手机都可以正常监听到通话的3个状态,but,这个破手机 TelephonyManager.CALL_STATE_IDLE 不返回,
最后用一个无法用理论解释的代码解决此问题,自定义一个service去录音,上代码:
package com.c.test.service;import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.widget.Toast;
import androidx.annotation.Nullable;
import com.blankj.utilcode.util.ToastUtils;
import java.io.File;
import com.c.base.MyApplication;
import com.c.base.bean.BaseResp;
import com.c.base.http.OnHttpResultListener;
import com.c.base.http.ResponseHandler;
import com.c.test.ui.model.MobileModel;
import com.c.test.utils.AudioRecordUtil;/*** 录音服务(用于录取通话记录)*/
public class AudioRecordService extends Service {private String id;private TelephonyManager manager;private CustomPhoneStateListener phoneStateListener;@Nullable@Overridepublic IBinder onBind(Intent intent) {return null;}@Overridepublic void onCreate() {super.onCreate();// 注册通话状态监听manager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);phoneStateListener = new CustomPhoneStateListener();manager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {id = intent.getStringExtra("id");return super.onStartCommand(intent, flags, startId);}@Overridepublic void onDestroy() {super.onDestroy();// 注销电话状态监听manager.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE);phoneStateListener = null;}/*** 通话状态监听器*/public class CustomPhoneStateListener extends PhoneStateListener {@Overridepublic void onCallStateChanged(int state, String phoneNumber) {super.onCallStateChanged(state, phoneNumber);Toast.makeText(getApplicationContext(), "state:" + state, Toast.LENGTH_SHORT).show();switch (state) {case TelephonyManager.CALL_STATE_RINGING:// 响铃状态ToastUtils.showShort("响铃状态");break;case TelephonyManager.CALL_STATE_OFFHOOK:// 接通状态,开始录音ToastUtils.showShort("接通状态,开始录音");AudioRecordUtil.getInstance(MyApplication.getInstance()).record(phoneNumber);// 此handler就是解决问题的关键,目前无法用理论解释,望路过大神指教下new Handler().post(new Runnable() {@Overridepublic void run() {}});break;case TelephonyManager.CALL_STATE_IDLE:// 空闲状态,停止录音ToastUtils.showShort("空闲状态,停止录音");AudioRecordUtil.getInstance(MyApplication.getInstance()).release();// 关闭自身服务stopSelf();break;}}}}
录音工具类:
package com.c.test.utils;import android.content.Context;
import android.media.MediaRecorder;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;/*** 录音工具类*/
public class AudioRecordUtil {private Context mContext;private MediaRecorder mediaRecorder;private static AudioRecordUtil mInstance;private File file;public static AudioRecordUtil getInstance(Context context) {if (mInstance == null) {mInstance = new AudioRecordUtil(context);}return mInstance;}public AudioRecordUtil(Context context) {mContext = context;}/*** 开始录音* @param phoneNumber 拨打的号码*/public void record(String phoneNumber) {if (mediaRecorder == null) {mediaRecorder = new MediaRecorder();if (phoneNumber == null) {phoneNumber = "null_";}// 录音存储路径String filePath = mContext.getExternalFilesDir(null).getAbsolutePath() + File.separator + "audioRecord";File directory = new File(filePath);if (!directory.exists()) {directory.mkdir();}
// String date = new SimpleDateFormat("yyyy.MM.DD HH:mm:ss", Locale.getDefault()).format(new Date());file = new File(filePath + File.separator + phoneNumber + "_" + System.currentTimeMillis() + ".3gp");try {if (!file.exists()) {file.createNewFile();}mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);mediaRecorder.setOutputFile(file.getAbsolutePath());mediaRecorder.prepare();mediaRecorder.start();} catch (IOException e) {e.printStackTrace();}}}public void release() {if (mediaRecorder != null) {mediaRecorder.stop();mediaRecorder.release();mediaRecorder = null;}}public File getFile() {return file;}
}
好了,又可以愉快玩耍了。
android 解决通话录音时无法返回挂断状态的bug相关推荐
- Android解决程序切换后台被干掉,恢复状态问题
Android解决程序切换后台被干掉,恢复状态问题 参考文章: (1)Android解决程序切换后台被干掉,恢复状态问题 (2)https://www.cnblogs.com/caiwan/p/And ...
- Android 来去电监听,电话挂断
android:enabled="true" android:process=":PhoneListenService"> public class Ph ...
- HFP:不活跃的车载设备在打电话时,不能挂断电话
Android P:Only active device can hung up call . 非 active device 不能挂断电话. step1:车载先连接 手机 step2:蓝牙耳机再连接 ...
- Android解决Unity游戏从后台返回黑屏问题
一. 问题现象 当有其他Activity在Unity所在的Activity之上的时候,Unity游戏从后台返回到游戏时,会出现黑屏的现象,比如: 正常时: 从后台返回时: 二. 问题分析 1)当Uni ...
- Android 解决程序启动时的黑屏问题
关于黑屏默认的情况下,程序启动时,会有一个黑屏的时期,原因是,首个activity会加载一些数据,比如初始化列表数据.向服务器发送请求获取数据等等. 去除方法: 1.在style里面添加一个style ...
- Android手机通话录音实现
最近在做语音IVR的时候需要对通话进行录音,主要用到了MediaRecorder类,实现代码如下: MediaRecorder mRecorder = new MediaRecorder();mRec ...
- SIP 通话三十秒自动挂断
上段时间搭建一个opensips server ,服务器存在NAT环境,sip uac 软电话都处于NAT外部.record_route中一开始是记录是NAT服务器内网地址,导致ACK无法正常返回到N ...
- Android监听来去电通话录音真正可实行方案,可获取电话接通时状态
最近 经过一段时间研究了Android来去电并且录音的研究,特此作为记录 首先监听来去电并且可以录音得有以下权限: //录音权限 <uses-permission android:name=&q ...
- Android ITelephony EndCall Remove 各版本挂断、拦截电话方法
本文首发地址:https://blog.csdn.net/CSqingchen/article/details/121426660 最新更新地址:https://gitee.com/chenjim/c ...
最新文章
- 系统架构师-基础到企业应用架构-表现层
- [转]一个典型的软件项目的WBS评析
- php or || 和 and
- 【BZOJ3518】点组计数 [欧拉函数]
- Github+Hexo搭建静态博客
- 进程间通信 - 命名管道实现
- 数据库原理及应用【三】DBMS+SQL
- 【转】C#中相同不同程序集存在相同的命名空间的时候的冲突解决办法
- python虚拟环境另类的搭建
- SEO人生衔接后用户可随时随地同他的合作伙伴协同工作
- Oracle(五)PL/SQL编程语言
- Excel数据分析实用小技巧【过坑】
- 大一acmer日常记录day15
- 敏捷合同VS传统合同
- FastReport.Net报表工具 vs RDL标准报表定义语言
- html banner广告代码,jquery实现的Banner广告收缩效果代码
- 小程序+二维码(带logo图片,可直接运行)
- python 生日悖论概率计算。
- Java毕业设计:校园二手闲置物品交易网站(java
- Java包名如何命名