这里以MTK4.0(6575/6577 6589)代码为基础进行分析。
源码下载http://download.csdn.net/detail/wds1181977/6387551
首先是Contacts.apk
拨号盘是依附于DialpadFragment上的。查看源码可以发现。无论是普通拨号还是视频拨号都会调用如下方法
protected void dialButtonPressedInner(String number, int type) { if (TextUtils.isEmpty(number)) { / .....} ...... final Intent intent = newDialNumberIntent(number, type); if (getActivity() instanceof DialtactsActivity) { intent.putExtra(DialtactsActivity.EXTRA_CALL_ORIGIN, DialtactsActivity.CALL_ORIGIN_DIALTACTS); } mCallOptionHandler.startActivity(intent); }
private Intent newDialNumberIntent(String number, int type) { final Intent intent = new Intent(Intent.ACTION_CALL_PRIVILEGED, Uri.fromParts("tel", number, null)); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); if((type & DIAL_NUMBER_INTENT_IP) != 0) intent.putExtra(Constants.EXTRA_IS_IP_DIAL, true); if((type & DIAL_NUMBER_INTENT_VIDEO) != 0) intent.putExtra(Constants.EXTRA_IS_VIDEO_CALL, true); return intent; }
public void startActivity(Intent intent) { ....... if(PhoneNumberUtils.isEmergencyNumber(mNumber) || intent.getIntExtra(Constants.EXTRA_SLOT_ID, -1) != -1) { final Intent broadcastIntent = newCallBroadcastIntent(mNumber, CallOptionHelper.DIAL_TYPE_VOICE, 0); mContext.sendBroadcast(broadcastIntent); return; } mCallOptionHelper.makeCall(intent); } else { intent.setClassName(Constants.PHONE_PACKAGE, Constants.OUTGOING_CALL_BROADCASTER); mContext.startActivity(intent); } Profiler.trace(Profiler.CallOptionHandlerLeaveStartActivity); }这里会判断是否是紧急拨号。如果是紧急拨号则调用 newCallBroadcastIntent返回的Intent发送广播。不是则CallOptionHandler.makeCall
public void makeCall(Intent intent) { int type = DIAL_TYPE_VOICE; if(intent.getBooleanExtra(Constants.EXTRA_IS_VIDEO_CALL, false)) type = DIAL_TYPE_VIDEO; final Uri uri = intent.getData(); final String scheme = uri.getScheme(); if(scheme.equals("sip") && !followSimSetting) type = DIAL_TYPE_SIP; if(Constants.VOICEMAIL_URI.equals(intent.getData().toString())) type = DIAL_TYPE_VOICE; ...... makeCall(number, type, originalSim); }
protected void makeCall(String number, int type, long originalSim) { .... switch(type) { case DIAL_TYPE_SIP: ..... break; case DIAL_TYPE_VIDEO:{ ..... break; case DIAL_TYPE_VOICE: makeVoiceCall(number, type, originalSim, callbackArgs); break; } mCallback.onMakeCall(callbackArgs); }
public void onMakeCall(final CallbackArgs args) { int slot = -1; switch (args.reason) { case CallOptionHelper.MAKE_CALL_REASON_OK: { if(args.type == CallOptionHelper.DIAL_TYPE_VOICE){ //获取slot } if(args.type == ...){ //获取slot } mIntent.putExtra(Constants.EXTRA_SLOT_ID, slot); .... afterCheckSIMStatus(com.mediatek.CellConnService.CellConnMgr.RESULT_STATE_NORMAL, slot); .... break; case MAKE_CALL_REASON_3G_SERVICE_OFF: ..... .... } } }
这里的mIntent为CallOptionHAndler.startActivity中的intent,在onMakeCall方法中加入了slot字段。然后调用afterCheckSIMStatus方法。
【笔者这里理解的slot字段是一个标志电话类型的标志位。如果slot =1 则是一般电话,slot = 0则是紧急拨号,slot<0则是没有插入SIM卡,不知道正确与否。】
private boolean afterCheckSIMStatus(int result, int slot) { ... // ip dial only support voice call boolean noSim = SIMInfoWrapper.getDefault().getInsertedSimCount() == 0; if(!mIntent.getBooleanExtra(Constants.EXTRA_IS_VIDEO_CALL, false) && mIntent.getBooleanExtra(Constants.EXTRA_IS_IP_DIAL, false) && !noSim) { .. } } // a little tricky here, check the voice mail number if(Constants.VOICEMAIL_URI.equals(mIntent.getData().toString())) { //VoiceMailNumber .. } } String number = getInitialNumber(mIntent); final int type = mIntent.getBooleanExtra(Constants.EXTRA_IS_VIDEO_CALL, false) ? CallOptionHelper.DIAL_TYPE_VIDEO : CallOptionHelper.DIAL_TYPE_VOICE; final Intent broadcastIntent = newCallBroadcastIntent(number, type, slot); mContext.sendBroadcast(broadcastIntent); return true; }
private Intent newCallBroadcastIntent(String number, int type, int slot) { Intent intent = new Intent(OUTGOING_CALL_RECEIVER); intent.setClassName(PACKAGE, OUTGOING_CALL_RECEIVER); if(type == CallOptionHelper.DIAL_TYPE_VIDEO) intent.putExtra(Constants.EXTRA_IS_VIDEO_CALL, true); if(type == CallOptionHelper.DIAL_TYPE_SIP) intent.setData(Uri.fromParts("sip", number, null)); else intent.setData(Uri.fromParts("tel", number, null)); intent.putExtra(Constants.EXTRA_SLOT_ID, slot); return intent; }