当我拿到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" />