当前位置:   article > 正文

android打电话流程_android 11 拨打电话

android 11 拨打电话

Android打电话流程

1. 所有流程的起点是从拨号后按下拨号键开始,此步的代码在/android sourcecode/packages/Contacts/src/com/android/contacts/目录的TwelveKeyDialer.java文件中,相关代码如下:

[cpp]view plaincopyprint?

dialButtonPressed() {  

.........  

final String number = mDigits.getText().toString();  

startActivity(newDialNumberIntent(number));  

mDigits.getText().clear();  

finish();  

}  

dialButtonPressed() {

......... 

final String number = mDigits.getText().toString(); 

startActivity(newDialNumberIntent(number));

mDigits.getText().clear();

finish(); 

}代码中newDialNumberIntent()方法定义如下:

[cpp]view plaincopyprint?

private Intent newDialNumberIntent(String number) {  

final Intent intent = new Intent(Intent.ACTION_CALL_PRIVILEGED, Uri.fromParts("tel", number, null));  

10 .............  

11 }  

private Intent newDialNumberIntent(String number) { final Intent intent = new Intent(Intent.ACTION_CALL_PRIVILEGED, Uri.fromParts("tel", number, null)); ............. }从newDialNumberIntent的定义可以看出,当拨号键按下以后,TwelveKeyDial会启动一个特定的组件,该组件的ACTION为:ACTION_CALL_PRIVILEGED,经过查找,该ACTION启动的组件是目录下:/android sourcecode/packeges/Phone/的一个文件,在该文件下的AndroidMenifest.xml中可以查到:“ACTION_CALL_PRIVILEGED”启动的Activity的名字是:PrivilegedOutgoingCallBroadcast,但是我们到/android sourcecode/packages/Phone/src/....目下并找不到该文件,因为该文件在AndroidMenifest.xml中标记有点特殊:

<activity-alias />,这个标签的意思是这个Activity是另一个Activity的别名,真实的Activity在标签中用“android:targetActivity = OutgoingCallBroadcast”标出,所以 “ACTION_CALL_PRIVILEGED”启动的 PrivilegedOutgoingCallBroadcast 所对应的真实“身份”是 “OutgoingCallBroadcast”。

2. 这个时候电话的数据已经流到OutgoingCallBroadcast.java中了。

在OutgoingCallBroadcast.java的onCreate()方法中有:

[java]view plaincopyprint?

12 <pre name="code" class="java">protected void onCreate(Bundle icicle) {  

13 .......  

14 Intent intent = getIntent();  

15 ........  

16 String action = intent.getAction();  

17 .......  

18 final boolean emergencyNum = (number != null) && PhoneNumUtils.isEmergencyNumber(number);//判断号码是否是紧急号码   

19 .......  

20 if (Intent.ACTION_CALL_PRIVILEGED.equals(action)) {  

21 action = emergencyNum ? Intent.ACTION_CALL_EMERGENCY : Intent.ACTION_CALL;  

22 intent.setAction(action);  

23 }  

24 .......  

25 intent.setClass(this, InCallScreen.class);  

26 startActivity(intent);  

27 }  

<pre name="code" class="java">protected void onCreate(Bundle icicle) { .......Intent intent = getIntent();........String action = intent.getAction(); ....... final boolean emergencyNum = (number != null) && PhoneNumUtils.isEmergencyNumber(number);//判断号码是否是紧急号码 .......if (Intent.ACTION_CALL_PRIVILEGED.equals(action)) { action = emergencyNum ? Intent.ACTION_CALL_EMERGENCY : Intent.ACTION_CALL; intent.setAction(action);}.......intent.setClass(this, InCallScreen.class); startActivity(intent);}

在这个方法中,判断如果所收到的ACTION是“ACTION_CALL_PRIVILEGED”,那么根据所输入的号码是否是紧急号码进行转换,如果是紧急号码,则ACTION = Intent.ACTION_CALL_EMERGENCY,否则ACTION = Intent.ACTION_CALL,并启动转换Activity :InCallScreen.java

3. InCallScreen.java依然在目录/packeges/Phone/src/com/android/phone下。

InCallScreen的onCreate中调用initInCallScreen初始化打电话界面,并调用registerForPhoneStates注册电话状态监听.

在onNewIntent()方法中有:

[java]view plaincopyprint?

28 protected void onNewIntent(Intent intent) {  

29 ..........  

30 String action  = intent.getAction();  

31 ..........  

32 else if (action.equals(Intent.ACTION_CALL) || action.equals(Intent.ACTION_CALL_EMERGENCY)) {  

33 ..........  

34 InCallInitStatus status = placeCall(intent);  

35 }  

36 }  

37 //placeCall   

38 private InCallInitStatus placeCall(Intent intent) {  

39 ..............  

40 int callStatus  = PhoneUtils.placeCall(........);  

41 }  

protected void onNewIntent(Intent intent) { ..........String action = intent.getAction();.......... else if (action.equals(Intent.ACTION_CALL) || action.equals(Intent.ACTION_CALL_EMERGENCY)) { ..........InCallInitStatus status = placeCall(intent);}}//placeCall private InCallInitStatus placeCall(Intent intent) {.............. int callStatus = PhoneUtils.placeCall(........); }InCallScreen.java中的placeCall方法调用PhoneUtils.java文件的placeCall方法

4. PhoneUtils.java依然在目录/packeges/Phone/src/com/android/phone下。

[java]view plaincopyprint?

42 public static int placeCall(...) {  

43 Connection connection;  

44 connection = PhoneApp.getInstance().mCM.dial(phone, numberToDial);  

45 }  

public static int placeCall(...) { Connection connection; connection = PhoneApp.getInstance().mCM.dial(phone, numberToDial); }继续追踪,在PhoneApp.java中发现,mCM是CallManager.java类的一个对象,而CallManager.java是属于frameworks层的,所以,这个时候数据流已经进入frameworks.

5. 进入/frameworks/base/telephony/java/com/android/internal/telephony目录。

在CallManager.java的dial()方法中,有:

[java]view plaincopyprint?

46 <span style="font-family: Arial, Verdana, sans-serif; white-space: normal; background-color: rgb(255, 255, 255); "></span><pre name="code" class="java">public Connection dial(Phone phone, String dialNumber) throws CallStateException {  

47 Phone basePhone = getPhoneBase(phone);  

48 Connection result;  

49 <span style="color:#3333ff;">result = basePhone.dial(dialString);</span>  

50 ........  

51 }  

52 private static Phone getPhoneBase(Phone phone) {  

53 if (phone instanceof PhoneProxy) {  

54 <span style="color:#ff0000;">return phone.getForegroundCall().getPhone();</span>  

55 }  

56 return phone;  

57 }  

<span style="font-family: Arial, Verdana, sans-serif; white-space: normal; background-color: rgb(255, 255, 255); "></span><pre name="code" class="java">public Connection dial(Phone phone, String dialNumber) throws CallStateException { Phone basePhone = getPhoneBase(phone);Connection result; <span style="color:#3333ff;">result = basePhone.dial(dialString);</span> ........}private static Phone getPhoneBase(Phone phone) { if (phone instanceof PhoneProxy) { <span style="color:#ff0000;">return phone.getForegroundCall().getPhone();</span> }return phone;}

[java]view plaincopyprint? 

58 <span style="font-family: Arial, Verdana, sans-serif; white-space: normal; background-color: rgb(255, 255, 255); ">继续追踪会发现:</span>  

<span style="font-family: Arial, Verdana, sans-serif; white-space: normal; background-color: rgb(255, 255, 255); ">继续追踪会发现:</span>

[java]view plaincopyprint? 

59 <span style="font-family: Arial, Verdana, sans-serif; white-space: normal; background-color: rgb(255, 255, 255); ">PhoneBase.java抽象类实现了接口Phone.java,而GSMPhone.java又实现了抽象类PhoneBase,所以:</span>  

<span style="font-family: Arial, Verdana, sans-serif; white-space: normal; background-color: rgb(255, 255, 255); ">PhoneBase.java抽象类实现了接口Phone.java,而GSMPhone.java又实现了抽象类PhoneBase,所以:</span>

上述代码中:phone.getForegroundCall()实际相当于GSMPhone对象执行了getForegroundCall()方法。

6. 继续追踪GSMPhone.java,该类位于/frameworks/base/telephony/java/com/android/internal/telephony/gsm/下。

[java]view plaincopyprint?

60 GSMPhone.java:  

61 GsmCallTracker mCT;  

62 public GsmCall getForegroundCall() {  

63 return mCT.foregroundCall;  

64 }  

GSMPhone.java:GsmCallTracker mCT; public GsmCall getForegroundCall() {return mCT.foregroundCall; }可以看出getForegroundCall()函数继续调用GsmCallTracker.java的foregroundCall属性。

7.GsmCallTracker.java位于/frameworks/base/telephony/java/com/android/internal/telephony/gsm/下.

[cpp]view plaincopyprint?

65 GsmCallTracker.java:  

66 GSMCall foregroundCall = new GSMCall(this);  

GsmCallTracker.java: GSMCall foregroundCall = new GSMCall(this);

打开GSMCall.java,找到getPhone()方法,发现:

[java]view plaincopyprint?

67 GSMCallTracker owner;  

68 public Phone getPhone() {  

69 return owner.phone;  

70 }  

GSMCallTracker owner; public Phone getPhone() {return owner.phone;}

而在GSMCallTracker.java中有如下声明:

[cpp]view plaincopyprint?

71 GSMPhone phone;  

GSMPhone phone;

到此,我们得出一下结论:第5部分标记红色的代码所返回的就是GSMPhone的对象,进一步可以得出,第5部分蓝色标记的代码即是调用了GSMPhone对象的dial方法。

8. 在GSMPhone.java中:

[java]view plaincopyprint?

72 GSMCallTracker mCT;  

73 public Connection dial(String dialString) throws CallStateException {  

74 return dial(dialString, null);  

75 }  

76   

77 public Connection dial(String dialString, UUSInfo uusInfo) throws CallStateException {  

78 .......  

79 mCT.dial(.......);  

80 }  

GSMCallTracker mCT; public Connection dial(String dialString) throws CallStateException { return dial(dialString, null);} public Connection dial(String dialString, UUSInfo uusInfo) throws CallStateException { .......mCT.dial(.......);}

继续调用GSMCallTracker.java中的dial()方法:

[cpp]view plaincopyprint?

81 GSMCallTracker.java:  

82 GSMCallTracker(GSMPhone phone) {  

83 cm = phone.mCM;  

84 }  

85 Connection dial(String dialString, int clirMode, UUSInfo uusInfo) {  

86 <span style="color:#ff0000;">cm.dial(........);</span>  

87 }  

GSMCallTracker.java: GSMCallTracker(GSMPhone phone) {cm = phone.mCM;} Connection dial(String dialString, int clirMode, UUSInfo uusInfo) { <span style="color:#ff0000;">cm.dial(........);</span>}追踪mCM,发现 :

public CommandsInterface mCM;

所以GSMCallTracker持有CommandsInterface对象,即RIL.Java类的对象,所以"cm.dial(....)"即是调用RIL类对象的dial()方法。

9. RIL.java

BOSS出现。

RIL对象负责把客户端的通话请求按照一定的格式发送给"rild"socket,至此,请求过程完毕。

 

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号