首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 移动开发 > 移动开发 >

拨通电话流程(Contacts-App层)

2012-09-29 
拨打电话流程(Contacts--App层)?? 这里以MTK4.0代码为基础进行分析。??首先是Contacts.apk??拨号盘是依附于

拨打电话流程(Contacts--App层)


拨通电话流程(Contacts-App层)
?? 这里以MTK4.0代码为基础进行分析。

?

?首先是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;    }

?

会加入Intent.ACTION_CALL_PRIVILEGED,Uri.fromParts("tel", number, null)和是否是VIDEO_CALL / IP_CALL的Extra.调用CallOptionHandler的StartActivity方法

 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);    }

?

这里又将Type类型分为3种? DIAL_TYPE_VOICE,DIAL_TYPE_VIDEO,DIAL_TYPE_SIP

 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);    }

?这里会根据type的类型去实现CallbackArgs callbackArgs对象的不同属性。其中这3种type会存放在callbackArgs.type属性中。然后调用mCallback.onMakeCall方法。查找可以知道onMakeCall是在CallOptionHandler里面实现的。

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;    }

?

?这里最后将调用newCallBroadcastIntent。我们发现紧急拨号或者其他的拨号,如果拨号成功,都是使用newCallBroadcastIntent返回的Intent来发送广播。

  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;    }

?到这里会发现,最后发送出去的intent只会包含2个有用的信息。就是Uri和Constants.EXTRA_SLOT_ID。最后该广播将在Phone.apk中的OutgoingCallReceiver中截获。

?

?

?

?

1 楼 h529820165 2012-09-13   补充下 最后发出去的广播还有个重要信息就是intent.putExtra(Constants.EXTRA_IS_VIDEO_CALL, true);  

热点排行