据了解,安卓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
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
// 注册通话状态监听
manager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
phoneStateListener = new CustomPhoneStateListener();
manager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
id = intent.getStringExtra("id");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
// 注销电话状态监听
manager.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE);
phoneStateListener = null;
}
/**
* 通话状态监听器
*/
public class CustomPhoneStateListener extends PhoneStateListener {
@Override
public 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() {
@Override
public 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;
}
}
好了,又可以愉快玩耍了。