网上有很多的资料,我这里整理一份属于自己的。当然其中的很多内容还是来自网络,无所不能的网络啊~~~
很多人的文章写Call的流程的时候,都是从OutgoingCallBroadcaster.java开始到RIL.java结束,java部分的确是这样。但为了更完美我将补充前面的TwelveKeyDialer.java, 及后续的RIL层的AT指令,这样便一条路走到尽头(其实GSM/CDMA模块中还有,这部分暂时不提)。 全部的代码在四个部分:package/../Contacts ,package/../Phone,frameworks/base/telephony/java/com/android/internal/telephony 及hardware/ril/reference-ril 文章中粘贴的代码,由于从2.0到2.2的移植,所以有些代码并不是和2.2源码中一致。 1、界面部分的TwelveKeyDialer.java,extends Activity implements View.OnClickListener... 这一部分在Contacts这个APP中,在你一个个按下按键时,可以从onClick()函数中看到会响按键音、接着afterTextChanged()会匹配联系人中包含你按下数字的联系人 当你按下dial键的时候则会进入Call的流程中。
2、进入OutgoingCallBroadcaster.java,extends Activity 上面start intent时就进入OutgoingCallBroadcaster的onCreate(),首先判断电话号码是否为emergencyNumber
如果是紧急号码,将callNow变量赋值为true,立即启动InCallScreen。如不是则通过发送广播进入OutgoingCallReceiver.java 该类是一个内部类,作用是接收OutgoingCallBroadcaster发送的广播,判断是否已经启动InCallScreen。没有启动的话就进行一些初始化,如:对OTA进行初始化。 接收到广播之后,从Intent里面取出电话号码及其URi。然后设置Intent为ACTION_CALL,并带上号码和uri。启动InCallScreen。关闭该OutgoingCallBroadcaster。
3 启动InCallScreen.java , extends Activity implements View.OnClickListener, View.OnTouchListener 它主要类主要是负责通话的界面,包括通话时间的显示、联系人头像、电话号码、通话状态、DTMFTwelveKeyDialer及菜单等的现实 在Call流程中所起到的作用简单概述如下:得到action为ACTION_CALL、或ACTION_CALL_EMERGENCY,直接placeCall(intent),然后将状态返回.
而在 placeCall(intent)中直接是调用PhoneUtils的接口 callStatus = PhoneUtils.placeCall(mPhone, number, contactUri); 在接下来就只 Connection cn = phone.dial(number),这个就是调用Phone interface。 you cannot assume the audio path is connected until PhoneStateChanged notification has occurred. 4、接下来就进入到了framework中的code,我们已一个cdma 电话为例,总结一下相关的几个类 Phone 、CDMAPhone、PhoneBase、CdmaCallTracker、CdmaConnection、CallTracker、CommandsInterface、RIL、BaseCommands共8个类,我们先整理一下这些类的关系 本人较懒,就不画UML图了,直接文字表达一下,呵呵~~ public interface Phone PhoneBase extends Handler implements Phone CDMAPhone extends PhoneBase 所以可以看到CDMAPhone中的dial()函数如下
mCT的定义也在CDMAPhone中 CdmaCallTracker mCT; 在mCT的dial()函数中有
这段代码主要注意3点 首先是pendingMO = new CdmaConnection(phone.getContext(), dialString, this, foregroundCall),这个是创建一个Call的connection实例,然后将其加入到 一个connections的list中,因为每个网络支持好几通电话。 其次是obtainCompleteMessage() { return obtainCompleteMessage(EVENT_OPERATION_COMPLETE);},这个是要处理返回信息的 最后还更新了Phone的状态,phone call的状态一共就3个
public final class CdmaCallTracker extends CallTracker CallTracker中定义public CommandsInterface cm; CommandsInterface为接口类 public interface CommandsInterface public abstract class BaseCommands implements CommandsInterface public final class RIL extends BaseCommands implements CommandsInterface 由于以上的这些关系,最后走到RIL.java的dial部分,这段代码不多说,就是往socket中写东西。这里先记住RIL_REQUEST_DIAL
其实到了这,我们暂时不去分析RIL层。先假设如果这通电话成功播出的话,应该是一个ATD<dial string>下去,然后返回一个OK。这个在上层是怎么处理的呢? 在RIL.java中有RILSender extends Handler implements Runnable 和RILReceiver implements Runnable,其实发送就是通过RILSender往socket中写data。 而接收AT就是就是从socket中读取data,然后处理。这里返回的OK会在processResponse()->processSolicited()中处理。如果返回没有错误最终是 走rr.mResult.sendToTarget(),然后出发CdmaCallTracker.java中的msg(EVENT_OPERATION_COMPLETE),可以看到 CdmaCallTracker.java中有handlemessage()
在operationComplete()中其实是将pendingOperations计数减1,然后获取当前的calls(这个一般对应AT+CLCC).这样便知道此时该网络的通话情况。
5、接下来,步入正轨。进入RIL层。 这里涉及的几个文件为 Ril_commands.h 中一个映射结构{RIL_REQUEST_DIAL, dispatchDial, responseVoid} Ril.h 主要定义一个宏 #define RIL_REQUEST_DIAL 10 ,其实这个必须和java层的RILConstants.java中定义的int RIL_REQUEST_DIAL = 10;一致,并且在 Ril_commands.h 中的顺序也应从上数第10行,不然的话会出错。这一点,设计的确实有些呆板。 Ril.cpp case RIL_REQUEST_DIAL: return "DIAL",这个是要是一个请求转换为string的操作 Reference-ril.c 中的
在requestDial()中
这样一个ATD通过at_send_command()写向串口(最终调用的是系统函数writeline()),剩下的就交给CDMA模块了。呵呵~~ |
|
来自: techres > 《Android预置应用》