打一个电话流程简介

来源:互联网 发布:sqlyog怎样导出sql文件 编辑:程序博客网 时间:2024/04/26 20:00

一个电话打出去流程分析

1.      配置文件AndroidManifest.xml

文件路径:packages/apps/Contacts/AndroidManifest.xml

其中属性android:enabled="@*android:bool/config_voice_capable"是用来控制应用是否在菜单中显示的,在禁用通话时会用到

   <activityandroid:name=".activities.BestoneDialtactsActivity"

           android:label="@string/launcherDialer"

           android:theme="@style/BestoneDialtactsTheme"

           android:uiOptions="splitActionBarWhenNarrow"

           android:launchMode="singleTask"

           android:clearTaskOnLaunch="true"

           android:icon="@drawable/ic_launcher_phone"

           android:screenOrientation="portrait"

           android:enabled="@*android:bool/config_voice_capable"

           android:taskAffinity="android.task.contacts.phone"

           android:windowSoftInputMode="stateAlwaysHidden|adjustPan"

           android:hardwareAccelerated="true">

                     ….

<intent-filter>

                <actionandroid:name="android.intent.action.MAIN" />

                <categoryandroid:name="android.intent.category.DEFAULT" />

                <categoryandroid:name="android.intent.category.LAUNCHER" />

                <categoryandroid:name="android.intent.category.BROWSABLE" />

           </intent-filter>

                     ……

</activity>

 

2.      在联系人目录中,从拨号盘界面,输入拨打号码,按下拨打按钮

(a). 拨号盘界面的构建

   文件路径:packages/apps/Contacts/src/com/android/contacts/activities/BestoneDialtactsActivity.java

          public void onCreate(Bundle icicle) {

......

//此布局是框架布局,嵌入搜索(SearchFragment),拨号盘(DialpadFragment)

setContentView(R.layout.bestone_dialtacts_activity);

......

}

       (b).按数字按钮和拨打按钮

          文件路径:packages/apps/Contacts/src/com/android/contacts/activities/BestoneDialtactsActivity.java

   public boolean onKeyDown(int keyCode,KeyEvent event) {

              ……

              handled = mDialpadFragment.onKeyDown(keyCode,event);

              ……

}

文件路径:packages/apps/Contacts/src/com/android/contacts/activities/DialpadFragment.javas

public booleanonKeyDown(int keyCode, KeyEvent event) {

         ……

         if (event.getKeyCode() ==KeyEvent.KEYCODE_CALL) {

                //如果点击的是拨打按钮,则拨出电话

                dialButtonPressed();

                return true;

         }

         //如果点击的是数字按钮,则作播放提示音等处理

         ……

}

public voiddialButtonPressed() {

         dialButtonPressedInner(mDigits.getText().toString(),

                Constants.DIAL_NUMBER_INTENT_NORMAL);

}

protected void dialButtonPressedInner(String number, int type) {

         ……

         //这里返回的intent指向com.android.phone.PrivilegedOutgoingCallBroadcaster(备注,在package/app/Phone目录下)

final Intent intent = ContactsUtils.getCallIntent(number,

                                      (getActivity() instanceofBestoneDialtactsActivity ? ((BestoneDialtactsActivity) getActivity())

                                            .getCallOrigin(): null), type);

         mCallOptionHandler.doCallOptionHandle(intent);

         ……

}

文件路径:packages/apps/Contacts/src/com/android/contacts/calloption/ContactsCallOptionHandler.java

public void doCallOptionHandle(Intent intent) {

        ……

            //获取Telephony服务的接口

        final ITelephonytelephony =

           ITelephony.Stub.asInterface(ServiceManager.getService(Context.TELEPHONY_SERVICE));

        ……

       SimAssociateHandler.getInstance(ContactsApplication.getInstance()).load();

            //启动到package/app/Phone/src/com/android/phone/PrevilegedOutgoingCallBroadcaster

       super.doCallOptionHandle(mActivityContext,ContactsApplication.getInstance(), intent,

                                this, ContactsApplication.getInstance().cellConnMgr,

                                telephony, SlotUtils.isGeminiEnabled(),

                                FeatureOption.MTK_GEMINI_3G_SWITCH);

            ……

}

 

3.      在电话目录下,接到Intent,继续将电话打出去

(a). 配置文件AndroidManifest.xml

文件路径:package/app/Phone/AndroidManifest.xml

<activity-aliasandroid:name="PrivilegedOutgoingCallBroadcaster"

               android:targetActivity="OutgoingCallBroadcaster"

               android:screenOrientation="nosensor"

               android:excludeFromRecents="true"

                android:permission="android.permission.CALL_PRIVILEGED">

                ……

</activity-alias>

       (b).文件路径:package/app/Phone/src/com/android/phone/OutgoingCallBroadcaster.java

   protected voidonCreate(Bundle icicle) {

        ……

        Intent intent =getIntent();

             //处理意图

        processIntent(intent);

}

     private voidprocessIntent(Intent intent) {       

        final Configurationconfiguration = getResources().getConfiguration();

        if(!PhoneGlobals.sVoiceCapable) {

            //如果禁用语言业务,则做相应处理

           handleNonVoiceCapable(intent);

            return;

        }

             //省略号码合法性检查,以及紧急号码的处理,点亮屏幕

             ……

             if (callNow) {

            ……

            // InCallScreen todisplay the in-call UI:

           PhoneGlobals.getInstance().callController.placeCall(intent);

                    ……

        }

}

(c). 文件路径:package/app/Phone/src/com/android/phone/CallController.java

       public voidplaceCall(Intent intent) {

        ......

              //获取拨号界面的状态,以便正确显示相应状态下UI

        final InCallUiStateinCallUiState = mApp.inCallUiState;

        ......

              //检查当前是否有前端通话或者后台通话,如果有先挂断这些通话

        PhoneConstants.Statestate = mCM.getState();

        if (isEccCall && state !=PhoneConstants.State.IDLE) {

            ......

                try {

                   mCM.hangupAllEx();

                   log("Waiting for disconnect exist calls.");

                    return;

                } catch (CallStateExceptione) {

                   log("catch exception = " + e);

                }

            }

                     ......

        }

        ......

              //拨打电话

        CallStatusCode status= placeCallInternal(intent);

        switch (status) {

            //拨打结果的处理

            case SUCCESS:

            case EXITED_ECM:

                 ....

           }

        ...... 

    }

       private CallStatusCodeplaceCallInternal(Intent intent) {

                ……

          callStatus =PhoneUtils.placeCall(mApp,

                        phone,

                       number,

                       contactUri,

                       (isEmergencyNumber || isEmergencyIntent),inCallUiState.providerGatewayUri);

                ……

    }

(d). 文件路径:package/app/Phone/src/com/android/phone/PhoneUtils.java

       public static intplaceCall(Context context, Phone phone,

                               String number, Uri contactRef, boolean isEmergencyCall,

                               Uri gatewayUri) {

        returnplaceCallGemini(context, phone, number, contactRef, isEmergencyCall,gatewayUri, -1);

    }

       public static intplaceCallGemini(Context context, Phone phone,

        String number, UricontactRef, boolean isEmergencyCall,

            Uri gatewayUri,int simId) {

                            ……

        try {

            // Google code:  connection = app.mCM.dial(phone,numberToDial);

            connection =GeminiRegister.dial(callManager, phone, numberToDial, simId);

        } catch(CallStateException ex) {

            ……

        }

}

文件路径:package/app/Phone/src/com/mediatek/phone/gemini/GeminiRegister.java

  public staticConnection dial(Object callManager, Phone phone, String numberToDial, intslotId)

            throwsCallStateException {

        ……

        Connectionconnection = null;

        try {

            if(GeminiUtils.isGeminiSupport() && !isSipPhone) {

                ……

               connection = ((MTKCallManager) callManager).dialGemini(phone,numberToDial, dialSlot);

            } else{

                            //到这里才算真正调用到Framework中接口方法

               connection = ((CallManager) callManager).dial(phone, numberToDial);

            }

        } catch(CallStateException ex) {

            ……

        }

        ……

  }

4.      Framework下调用Telephony相关接口,将电话拨出

文件路径:framework/opt/telephony/src/java/com/android/internal/telephony/CallManager.java

publicConnection dial(Phone phone, String dialString) throws CallStateException {

       //根据Phone类型,获得GSMPhone或者CDMAPhone实例

Phone basePhone = getPhoneBase(phone);

       ......

       result = basePhone.dial(dialString);

              ......

      }

       文件路径:framework/opt/telephony/src/java/com/android/internal/telephony/gsm/GSMPhone.java

       publicConnection dial(String dialString) throws CallStateException {

       return dial(dialString, null);

}

publicConnection dial (String dialString, UUSInfo uusInfo) throws CallStateException{

        //对MMI码作处理

……

        if (mmi == null) {

            return mCT.dial(newDialString,uusInfo);

}

}

文件路径:framework/opt/telephony/src/java/com/android/internal/telephony/gsm/

未完待续。。。。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

0 0
原创粉丝点击