当我拿到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;
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
@Override
public 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("创建服务---------------------");
}
@Override
public 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() {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
try {
System.out.println(">>>>>>CallState>>>>>>>>" + state); //输出 的是0 和 2
switch (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_GPP
mediaRecorder.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() {
@Override
public 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();
}
}
@Override
public 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" />