通话录音

来源:互联网 发布:js制作选项卡 编辑:程序博客网 时间:2024/04/28 17:22

当我拿到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" />
0 0
原创粉丝点击