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

来源:互联网 发布:网络主播常用语 编辑:程序博客网 时间:2024/06/07 16:11


   这里以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;    }

会加入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中截获。


原创粉丝点击