ImageVerifierCode 换一换
格式:DOCX , 页数:11 ,大小:306.68KB ,
资源ID:6990453      下载积分:8 金币
快捷注册下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

开通VIP
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.zixin.com.cn/docdown/6990453.html】到电脑端继续下载(重复下载【60天内】不扣币)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

开通VIP折扣优惠下载文档

            查看会员权益                  [ 下载后找不到文档?]

填表反馈(24小时):  下载求助     关注领币    退款申请

开具发票请登录PC端进行申请

   平台协调中心        【在线客服】        免费申请共赢上传

权利声明

1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前可先查看【教您几个在下载文档中可以更好的避免被坑】。
5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
6、文档遇到问题,请及时联系平台进行协调解决,联系【微信客服】、【QQ客服】,若有其他问题请点击或扫码反馈【服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【版权申诉】”,意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:0574-28810668;投诉电话:18658249818。

注意事项

本文(Android通话过程分析.docx)为本站上传会员【a199****6536】主动上传,咨信网仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知咨信网(发送邮件至1219186828@qq.com、拔打电话4009-655-100或【 微信客服】、【 QQ客服】),核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载【60天内】不扣币。 服务填表

Android通话过程分析.docx

1、Android通话过程分析 本文档主要对android平台下的call的实现做详细分析。 Call处理的五大核心分别是:Call,Phone, CallTracker,DriverCall,Connection 1. Call Call是Call应用中的最基本的单位,其主要是用来管理Connection的。Call中非常重要的是其状态,Call中共有九种状态: IDLE, ACTIVE, HOLDING, DIALING, ALERTING, INCOMING, WAITING, DISCONNECTED, DISCONNECTING; 对call的处理实际上是对状态转换上的处

2、理。对这九中状态所对应的含义和call此时的现状要很熟。 Call的继承关系图: Call是一个抽象类,从图中可知,实际操作是在其子类GsmCall和CdmaCall。在GsmCall中,有个成员变量:connections,这个变量是用来管理Call中的connection的,一个Call最大允许有5个connections: static final int MAX_CONNECTIONS_PER_CALL = 5; // only 5 connections allowed per call 2. Phone Phone不仅是call的处理核心,而且是整个Telep

3、hony处理的核心。Phone是一个最基本的概念,用来控制Phone系统相关(即无线相关的)模块的处理:simcard,call,message,datacall等。 Phone的继承关系如下: 在Phone的继承关系中可知,Phone只是一个接口,它被PhoneBase和PhoneProxy实现,而PhoneBase是抽象类,它被GsmPhone和CdmaPhone继承。所以有此可知Phone分为两类:GsmPhone和CdmaPhone。 PhoneBase还有另外一个继承关系:继承自Handler。这就说明GsmPhone和CdmaPhone其实都是一个Handler。

4、所以PhoneBase的子类是可以进行事件处理的。 3. Connection Connection用来处理一个真正的通话通路,包含通话过程中call的数据,包括号码、通话时间、MT还是MO、是第几路通话、挂断原因等信息。 Connection类关系图: GsmConnection中有个成员变量:GsmCall parent,这个成员变量是用来表示该connection是属于哪个Call的。由变量名(parent)可以看出Call与Connection的关系:父与子的关系,一个Call可以有多个Connection(3gpp中规定最多5个),但一个Connection只

5、能属于一个Call。 所以一个Connection必定要依附于一个Call。Connection是怎样依附于一个Call的呢?从Connection的构造方法中就可以知道: a. GsmConnection (Context context, DriverCall dc, GsmCallTracker ct, int index) 这个构造方法是在MT的时候使用的,因为它有一个DriverCall的参数。它通过parentFromDCState方法来获得对应的parent(Call)且通过parent.attach(this, dc);把connection加入到Call的Conne

6、ctions变量进行管理。 b. GsmConnection (Context context, String dialString, GsmCallTracker ct, GsmCall parent) 这个构造方法是在MO的时候使用的,它会传入一个指定的parent(Call)且通过parent.attachFake(this, GsmCall.State.DIALING);调用把Connection加入到Call的Connections变量进行管理。 从上面知道Connection调用了Call的2个重要的方法:Attach和attachFake。这两个方法都是把一个conn

7、ection加入到Call的Connections成员变量中进行管理的。Call中还有一个方法detach(GsmConnection conn),这个方法是用来把connection从Call中移除的。 其中还有一个方法:/*package*/ boolean update (DriverCall dc)。这个是用来更新connection的。 4. DriverCall 是与ril层通信时的一个中间处理类,主要用来接收到ril的call数据后转到到java层上来。 DriverCall中包含了协议中规定的有关call的相关参数,具体如下: public int index

8、 //Connection Index for use with, eg, AT+CHLD public boolean isMT; //是incoming还是outgoing public State state; //connection state。 public boolean isMpty;// nonzero if is mpty call。 public String number;// Remote party number public int TOA; //type of address, eg 145 = intl public boolean isVoi

9、ce;// nonzero if this is is a voice call public boolean isVoicePrivacy;// nonzero if CDMA voice privacy mode is active public int als;// ALS line indicator if available (0 = line 1) public int numberPresentation;// 0=Allowed, 1=Restricted, 2=Not Specified/Unknown 3=Payphone public String name;//

10、 Remote party name public int namePresentation;// 0=Allowed, 1=Restricted, 2=Not Specified/Unknown 3=Payphone 5. CallTracker CallTracker的类关系图: 从上图中可以看到,CallTracker 在本质上是一个Handler。 CallTracker是一个抽象类,所以其实际的操作对象是其子类:GSMCallTracker和CdmaCallTracker。 下面以GSMCallTracker为例介绍CallTracker的相关处理,CdmaCallT

11、racker处理基本与之相同。 GSMCallTracker是Android 的通话管理层。GSMCallTracker建立了ConnectionList 来管理现行的通话连接,并向上层提供电话调用接口。 1) Connections Connections是GSMCallTracker 用来维护所有的通话的列表,最大可维护7路通话。 static final int MAX_CONNECTIONS = 7; // only 7 connections allowed in GSM 2) ringingCall、foregroundCall、backgroundCall

12、 一个手机系统只允许3个Call同时存在,即ring call、active call和held call,所以GSMCallTracker用ringingCall、foregroundCall、backgroundCall来管理。 ringingCall:用来管理INCOMING和WAITING的通话 foregroundCall:用来管理DAILING、ALERTING、ACTIVE的通话 backgroundCall:用来管理HOLD的通话 那么,ringingCall、foregroundCall、backgroundCall是如何来管理对应的call和connection

13、的呢?前面已经讲过了Call和Connection及它们之间的关系,其实系统中的Call是已经存在的,就是上面的3个,其实主要的是对于一个connection,它需要依附于那个call,由connection的构造方法知: 1) 在 从RIL获取的Calls列表的时候,通过parentFromDCState来获取相应的Call: private GsmCall parentFromDCState (DriverCall.State state) { switch (state) { case ACTIVE:

14、 case DIALING: case ALERTING: return owner.foregroundCall; //break; case HOLDING: return owner.backgroundCall; //break; case INCOMING: case WAITING: return o

15、wner.ringingCall; //break; default: throw new RuntimeException("illegal call state: " + state); } } 2) 在其他情况下,一般根据上面的状态直接传入对应的call。 3) GsmCallTracker中的事件处理机制 Call的事件处理基本上是请求应答模式,具体如下(以dail为例,其他类同): 其中涉及到3个变量的处理: protected i

16、nt pendingOperations; protected boolean needsPoll; protected Message lastRelevantPoll; pendingOperations:顾名思义,这个变量是在发生请求的时候会++,在处理应答的时候会--。 needsPoll:该变量是用来配合pendingOperations处理是否需要从RIL获取当前calls列表,并更新connections列表。 lastRelevantPoll:在发送RIL_REQUEST_GET_CURRENT_CALLS的时候记录最近一次请求的message,在response

17、的时候只对最近一次请求的response做出响应,更新connections列表。 上面的3个变量主要是用来判断是否需要发送RIL_REQUEST_GET_CURRENT_CALLS请求来从RIL获取当前的calls列表,并更新connections列表。 GsmCallTracker事件处理的核心是一个异步事件的处理,在发送请求后等待回应的时候,用户有可能会继续的发送对应的请求,然后会有多个response同时上报过来,上面的3个变量主要是为了更好的处理这种情况,不管用户发送了多少次请求,pendingOperations都会记录下来;而且只要用户发送了一次

18、请求,needsPoll就为true,即就需要从RIL获取最新的call列表。所以只有当pendingOperations==0 并且 needsPoll == true的时候才发送RIL_REQUEST_GET_CURRENT_CALLS请求去获取Calls列表。 if (pendingOperations == 0 && needsPoll) { lastRelevantPoll= obtainMessage(EVENT_POLL_CALLS_RESULT); cm.getCurrentCalls(lastRelevant

19、Poll); } 由于中间可能发送了多次RIL_REQUEST_GET_CURRENT_CALLS请求,在多次发送此请求的过程中却没有一次response回来,最后的结果是到最后肯定会有多个response上来,而此时我们只需要更新一次就够了,lastRelevantPoll就是用来处理这个事情的:lastRelevantPoll记录了最近一次发送RIL_REQUEST_GET_CURRENT_CALLS请求时的response message,当返回的response message是最后一个时就更新Connections列表。 4) GsmCallTra

20、cker的核心处理方法----更新connections列表处理方法 protected void handlePollCalls(AsyncResult ar)的处理分析 handlePollCalls(AsyncResult ar) { List polledCalls; if(DBG_POLL) log(">handlePollCalls"); if (ar.exception == null) { //没有异常,取得calllists列表 polledCalls = (List)ar.result; } else if (

21、isCommandExceptionRadioNotAvailable(ar.exception)) { //如果radio是RADIO_NOT_AVAILABLE,则挂断所有的calls,这里的意思是所有的DriverCall是null。 polledCalls = new ArrayList(); } else { //其他的异常的话,推迟POLL_DELAY_MSEC = 250后再发送//RIL_REQUEST_GET_CURRENT_CALLS去获取DriverCall列表。 pollCallsAfterDelay();

22、 return; } Connection newRinging = null; //or waiting boolean hasNonHangupStateChanged = false; // Any change besides // a dropped connection boolean needsPollDelay = false; boolean unknownConnectionAppeared = false;

23、 //遍历DriverCall和Connections,根据不同情况做相应处理。 for (int i = 0, curDC = 0, dcSize = polledCalls.size() ; i < connections.length; i++) { GsmConnection conn = connections[i]; DriverCall dc = null; // polledCall list is sparse if (curDC < dcSize) {

24、 dc = (DriverCall) polledCalls.get(curDC); //此处说明connections数组的index+1就是callId,也即dc.index。 if (dc.index == i+1) { curDC++; } else { dc = null; } } if (conn == null && dc != n

25、ull) { //conn为null,说明CallTracker中是没有对应的call的,这只有两种情况可以//发生:MO的dialing状态和MT的incoming/waiting状态。打电话和来电的时候//会执行到此处。 } else if (conn != null && dc == null) { //说明在底层已经挂掉了,CallTracker需要drop该connection。对方挂断电话//的时候就会执行到此处。 } else if (conn != null && dc != null && !pare

26、To(dc)) { //此处说明对应的connection和dc并不是同一个call,这种情况下就需要drop //当前的connection并根据dc重新构建一个。此处应该是一个异常的处理情况。 } else if (conn != null && dc != null) { //此处表明connection和dc是同一个call,随后根据dc来更新connection。 } if (REPEAT_POLLING) {} } if (pending

27、MO != null) { //此时dial请求已经发送给ril但是对应的response还没有上来的情况。正常情况//下,到此时pengdingMO应该为null了,但是假如在dial后的response还没有上//来的时候做了其他动作,如hangup call,则此时很可能就执行到此处。 droppedDuringPoll.add(pendingMO); pendingMO = null; hangupPendingMO = false; } if (newRinging != null) {

28、 //表示是一个MT call,需要通知用户。 phone.notifyNewRingingConnection(newRinging); } // clear the "local hangup" and "missed/rejected call" // cases from the "dropped during poll" list // These cases need no "last call fail" reason for (int i = droppedDuringPoll.size() - 1;

29、i >= 0 ; i--) { GsmConnection conn = droppedDuringPoll.get(i); if (conn.isIncoming() && conn.getConnectTime() == 0) { // Missed or rejected call Connection.DisconnectCause cause; if (conn.cause == Connection.DisconnectCause.LOCAL) {

30、 cause = Connection.DisconnectCause.INCOMING_REJECTED; } else { cause = Connection.DisconnectCause.INCOMING_MISSED; } droppedDuringPoll.remove(i); conn.onDisconnect(cause); } else if (conn.cause == Connection.Disco

31、nnectCause.LOCAL) { // Local hangup droppedDuringPoll.remove(i); conn.onDisconnect(Connection.DisconnectCause.LOCAL); } else if (conn.cause == Connection.DisconnectCause.INVALID_NUMBER) { droppedDuringPoll.remove(i);

32、 conn.onDisconnect(Connection.DisconnectCause.INVALID_NUMBER); } } // Any non-local disconnects: determine cause if (droppedDuringPoll.size() > 0) { //本地挂断都是DisconnectCause.LOCAL,此处表明是对方或网络端的挂断,具体//挂断原因需要从RIL处获得。 cm.getLastCallFailCause( obtainNoPo

33、llCompleteMessage(EVENT_GET_LAST_CALL_FAIL_CAUSE)); } if (needsPollDelay) { pollCallsAfterDelay(); } // Cases when we can no longer keep disconnected Connection's // with their previous calls // 1) the phone has started to ring // 2) A Call/Connection

34、object has changed state... // we may have switched or held or answered (but not hung up) if (newRinging != null || hasNonHangupStateChanged) { internalClearDisconnected(); } 更新Phone的状态。 updatePhoneState(); if (unknownConnectionAppeared) { p

35、hone.notifyUnknownConnection(); } if (hasNonHangupStateChanged || newRinging != null) { //通知用户callstatechange。 phone.notifyPreciseCallStateChanged(); } if(DBG_POLL) log("

36、rolState(int) answerCall(Phone) hangup(Phone) hangupRingingCall(Phone) hangupActiveCall(Phone) hangupHoldingCall(Phone) hangupRingingAndActive(Phone) hangupAllCalls(Phone) hangup(Call) hangupAllConnections(Call) hangup(Connection) answerAndEndHolding(Phone) answerAndEndActive(Phone) pla

37、ceCall(Phone, String, Uri) placeCallVia(Context, Phone, String, Uri, Uri) switchHoldingAndActive(Phone) mergeCalls(Phone) isConferenceCall(Call) showIncomingCallUi(int) turnOnSpeaker(Context, boolean, boolean) restoreSpeakerMode(Context) isSpeakerOn(Context) turnOnNoiseSuppression(Context,

38、boolean, boolean) restoreNoiseSuppression(Context) setMute(Phone, boolean) getMute(Phone) setAudioMode(Context, int) okToS(Phone) okToMergeCalls(Phone) okToAddCall(Phone) 外部进程或应用需要使用call时,如hardware键接听和挂断电话等,此时的接口是PhoneInterfaceManager类所提供,此类继承自ITelephony.Stub,是aidl接口。 PhoneUtils中有一个static子类:ConnectionHandler,其主要是用来处理Mute设置相关的,其中主要是更新sConnectionMuteTable并根据当前phone的状态来控制mute设置。

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服