安卓通话状态监控 1

 <span style="font-size:14px;">private void processHangupCall() {
        if (DBG) log("try to processHangupCall");
       
        if (isVirtualCallInProgress()) {
            terminateScoUsingVirtualVoiceCall();
        } else {
            if (mPhoneProxy != null) {
                try {
                    mPhoneProxy.hangupCall();
                } catch (RemoteException e) {
                    Log.e(TAG, Log.getStackTraceString(new Throwable()));
                }
            } else {
                Log.e(TAG, "Handsfree phone proxy null for hanging up call");
            }
        }
    }</span>

这段代码就是执行了挂电话,其中的mPhoneProxy在别的地方被初始化过

private ServiceConnection mConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder service) {
            if (DBG) Log.d(TAG, "Proxy object connected");
            mPhoneProxy = IBluetoothHeadsetPhone.Stub.asInterface(service);
        }

        public void onServiceDisconnected(ComponentName className) {
            if (DBG) Log.d(TAG, "Proxy object disconnected");
            mPhoneProxy = null;
        }
    };

这个挂电话是进来的电话挂机还是出去的电话挂机理论上应该是一样的,因为都是断开链接

下面也是挂电话的部分

static boolean hangup(CallManager cm) {
        boolean hungup = false;
        Call ringing = cm.getFirstActiveRingingCall();
        Call fg = cm.getActiveFgCall();
        Call bg = cm.getFirstActiveBgCall();

        if (!ringing.isIdle()) {
            log("hangup(): hanging up ringing call");
            hungup = hangupRingingCall(ringing);
        } else if (!fg.isIdle()) {
            log("hangup(): hanging up foreground call");
            hungup = hangup(fg);
        } else if (!bg.isIdle()) {
            log("hangup(): hanging up background call");
            hungup = hangup(bg);
        } else {
            // No call to hang up!  This is unlikely in normal usage,
            // since the UI shouldn't be providing an "End call" button in
            // the first place.  (But it *can* happen, rarely, if an
            // active call happens to disconnect on its own right when the
            // user is trying to hang up..)
            log("hangup(): no active call to hang up");
        }
        if (DBG) log("==> hungup = " + hungup);

        return hungup;
    }

static boolean hangup(Call call) {
        try {
            CallManager cm = getCallManager();

            if (call.getState() == Call.State.ACTIVE && cm.hasActiveBgCall()) {
                // handle foreground call hangup while there is background call
                log("- hangup(Call): hangupForegroundResumeBackground...");
                cm.hangupForegroundResumeBackground(cm.getFirstActiveBgCall());
            } else {
                log("- hangup(Call): regular hangup()...");
                call.hangup();
            }
            return true;
        } catch (CallStateException ex) {
            Log.e(LOG_TAG, "Call hangup: caught " + ex, ex);
        }

        return false;
    }

 public boolean hangupCall() {
            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
            if (mCM.hasActiveFgCall()) {
                return PhoneUtils.hangupActiveCall(mCM.getActiveFgCall());
            } else if (mCM.hasActiveRingingCall()) {
                return PhoneUtils.hangupRingingCall(mCM.getFirstActiveRingingCall());
            } else if (mCM.hasActiveBgCall()) {
                return PhoneUtils.hangupHoldingCall(mCM.getFirstActiveBgCall());
            }



参考这个文章http://blog.csdn.net/guiyu_1985/article/details/7518026

接下来是监听本次通话的状态,比如对方未接听就挂了,对方接听后挂了,没有sim卡电话没有打出,有sim卡没服务电话不通等等。


private void sendClccResponseCdma(int index, Connection connection) {
        int state;
        PhoneGlobals app = PhoneGlobals.getInstance();
        CdmaPhoneCallState.PhoneCallState currCdmaCallState =
                app.cdmaPhoneCallState.getCurrentCallState();
        CdmaPhoneCallState.PhoneCallState prevCdmaCallState =
                app.cdmaPhoneCallState.getPreviousCallState();

        if ((prevCdmaCallState == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE)
                && (currCdmaCallState == CdmaPhoneCallState.PhoneCallState.CONF_CALL)) {
            // If the current state is reached after merging two calls
            // we set the state of all the connections as ACTIVE
            state = CALL_STATE_ACTIVE;
        } else {
            Call.State callState = connection.getState();
            switch (callState) {
            case ACTIVE:
                // For CDMA since both the connections are set as active by FW after accepting
                // a Call waiting or making a 3 way call, we need to set the state specifically
                // to ACTIVE/HOLDING based on the mCdmaIsSecondCallActive flag. This way the
                // CLCC result will allow BT devices to enable the swap or merge options
                if (index == 0) { // For the 1st active connection
                    state = mCdmaIsSecondCallActive ? CALL_STATE_HELD : CALL_STATE_ACTIVE;
                } else { // for the 2nd active connection
                    state = mCdmaIsSecondCallActive ? CALL_STATE_ACTIVE : CALL_STATE_HELD;
                }
                break;
            case HOLDING:
                state = CALL_STATE_HELD;
                break;
            case DIALING:
                state = CALL_STATE_DIALING;
                break;
            case ALERTING:
                state = CALL_STATE_ALERTING;
                break;
            case INCOMING:
                state = CALL_STATE_INCOMING;
                break;
            case WAITING:
                state = CALL_STATE_WAITING;
                break;
            default:
                Log.e(TAG, "bad call state: " + callState);
                return;
            }
        }

        boolean mpty = false;
        if (currCdmaCallState == CdmaPhoneCallState.PhoneCallState.CONF_CALL) {
            if (prevCdmaCallState == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE) {
                // If the current state is reached after merging two calls
                // we set the multiparty call true.
                mpty = true;
            } // else
                // CALL_CONF state is not from merging two calls, but from
                // accepting the second call. In this case first will be on
                // hold in most cases but in some cases its already merged.
                // However, we will follow the common case and the test case
                // as per Bluetooth SIG PTS
        }

        int direction = connection.isIncoming() ? 1 : 0;

        String number = connection.getAddress();
        int type = -1;
        if (number != null) {
            type = PhoneNumberUtils.toaFromString(number);
        } else {
            number = "";
        }

        mBluetoothHeadset.clccResponse(index + 1, direction, state, 0, mpty, number, type);
    }

或者

static int convertCallState(Call.State callState) {
        switch (callState) {
        case IDLE:
        case DISCONNECTED:
        case DISCONNECTING:
            return CALL_STATE_IDLE;
        case ACTIVE:
            return CALL_STATE_ACTIVE;
        case HOLDING:
            return CALL_STATE_HELD;
        case DIALING:
            return CALL_STATE_DIALING;
        case ALERTING:
            return CALL_STATE_ALERTING;
        case INCOMING:
            return CALL_STATE_INCOMING;
        case WAITING:
            return CALL_STATE_WAITING;
        default:
            Log.e(TAG, "bad call state: " + callState);
            return CALL_STATE_IDLE;
        }
    }

以上两段代码都是针对这个

Call.State callState = connection.getState();
            switch (callState) {

所以关键是取得这个callstate,这个connection的来源在

sendClccResponseCdma(i, clccConnections[i]);
这个clccConnections[i]的来源是

 Connection[] clccConnections = new Connection[CDMA_MAX_CONNECTIONS];// indexed by CLCC index

这个Connection的class在framework里

初始化是

 clccConnections[0] = foregroundCall.getLatestConnection();
继续找初始化

Call foregroundCall = mCM.getActiveFgCall();

private CallManager mCM;

  mCM = CallManager.getInstance();

在eclipse中无法导入callmanager的包,这个才是大问题


 public Call.State getActiveFgCallState() {
        Call fgCall = getActiveFgCall();

        if (fgCall != null) {
            return fgCall.getState();
        }

        return Call.State.IDLE;
    }

这边可以获取state;而且不需要依赖别的函数和变量;关于fgcall也可以参考http://www.360doc.com/content/13/0222/09/8841214_267189922.shtml







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值