首先去找那个buttom图标在哪
<ImageButton android:id="@+id/endButton"
然后看code里哪里用到了它
<span style="font-size:18px;">case R.id.endButton:
internalHangup();
break;</span>
追踪 internalHangup();
<span style="font-size:18px;"> private void internalHangup() {
PhoneConstants.State state = mCM.getState();
log("internalHangup()... phone state = " + state);</span>
<span style="font-size:18px;"> PhoneUtils.hangup(mCM);
</span>
<span style="font-size:18px;">if (state == PhoneConstants.State.IDLE) {
Log.w(LOG_TAG, "internalHangup(): phone is already IDLE!");
</span>
<span style="font-size:18px;"> }
}
</span>
原来也是用了PhoneUtils.hangup(mCM);
搜索mCM
setPhone(DualPhoneController.getInstance().getActivePhone(),
DualPhoneController.getInstance().getActiveCM());
搜索DualPhoneController.getInstance().getActiveCM()
CallManager getActiveCM() {
if (isPrimaryOnSim1()) {
return mActiveSimId == ID_SIM_1 ? mApp.mCM : mApp.mCM2;
}
return mActiveSimId == ID_SIM_1 ? mApp.mCM2 : mApp.mCM;
}
搜索mApp.mCM
mCM = CallManager.getInstance();
mCM.registerPhone(phone);
mCM2 = CallManager.getInstance2();
mCM2.registerPhone(phone2);
搜索phone
phone = PhoneFactory.getDefaultPhone();
phone2 = PhoneFactory.get2ndPhone();
所以归根结底是这个
<span style="font-size:18px;"> 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;
}</span>
搜索 hungup = hangup(fg);<span style="font-size:18px;"> 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;
}</span>
搜索
<span style="font-size:18px;"> cm.hangupForegroundResumeBackground(cm.getFirstActiveBgCall());</span>
找到
<span style="font-size:18px;">public void hangupForegroundResumeBackground(Call heldCall) throws CallStateException {
Phone foregroundPhone = null;
Phone backgroundPhone = null;
if (VDBG) {
Rlog.d(LOG_TAG, "hangupForegroundResumeBackground(" +heldCall + ")");
Rlog.d(LOG_TAG, toString());
}
if (hasActiveFgCall()) {
foregroundPhone = getFgPhone();
if (heldCall != null) {
backgroundPhone = heldCall.getPhone();
if (foregroundPhone == backgroundPhone) {
getActiveFgCall().hangup();
} else {
// the call to be hangup and resumed belongs to different phones
getActiveFgCall().hangup();
switchHoldingAndActive(heldCall);
}
}
}
if (VDBG) {
Rlog.d(LOG_TAG, "End hangupForegroundResumeBackground(" +heldCall + ")");
Rlog.d(LOG_TAG, toString());
}
}</span>
然后getActiveFgCall()
<span style="font-size:18px;">public Call getActiveFgCall() {
Call call = getFirstNonIdleCall(mForegroundCalls);
if (call == null) {
call = (mDefaultPhone == null)
? null
: mDefaultPhone.getForegroundCall();
}
return call;
}</span>
也就是说,这个hangup其实是call类型里的hangup,关键在于先构建一个call类型的对象