人人范文网 范文大全

Android RIL&Call学习总结

发布时间:2020-03-02 02:27:13 来源:范文大全 收藏本文 下载本文 手机版

Android RIL与Call代码学习总结

前言

本文分五部分:Android电信业务系统、RIL、Telephony APP Framework、Phone APP、Android通话简单流程。

1、Android电信业务系统主要叙述Android整个电信业务系统的软件架构。

2、RIL主要叙述Android Radio Interface Layer相关要点,涉及的代码主要放在\\hardware\\ril目录下。

3、Telephony APP Framework主要简述电信业务系统Framework部分代码相关要点,涉及的代码主要放在\\frameworks\\base\\telephony目录下。

4、Phone APP主要叙述Android的电话业务模块,涉及的代码主要放在\\packages\\apps\\Phone目录下。

5、Android通话简单流程主要叙述从上层Phone APP发起电话的函数调用流程。

一、Android电话业务系统

简单的说由三部分组成:Telephony Application(Java) + Telephony Frameworks(Java) + RIL(C/C++)

二、RIL RIL(Radio Interface Layer),是Android电信业务系统和底层硬件之间的抽象层,Android提供该层方便用户移植。手机每次请求相应的电信服务,如电话、短信、网络连接等,都是通过AT指令与底层硬件进行交互的,拿电话来讲,用户请求拨打电话,需要向RIL发送相关的请求,接着RIL按照用户的请求,调用相应的AT指令发送接口给底层发送AT指令,完成用户拨打电话的流程。简单的说,对RIL的移植,主要是针对不同的设备针对AT指令做相应的修改。

1、RIL移植层的三个组成部分

1) Vendor RIL 提供AT指令发送接口 2) RIL Daemon 加载RIL相关的库同时初始化RIL,注册RIL相关函数接口。同时,RILD也是上层和底层RIL的调用中转站。 3) RIL JNI Layer RIL JNI接口,提供上层Telephony APP Framework调用

2、RIL的初始化流程

加载ril.lib  RIL_Init()  RIL_register(),详细可见ridl.c中的main()函数。

3、RIL接口的调用方式

有两种方式:主动请求(Solicited)和被动请求(Unsolicited) 1)主动请求

2)被动请求

void (*OnUnsolicitedResponse)(int unsolResponse, const void *data,size_t datalen);

4、涉及的主要源代码文件

1)reference-ril.c  本文件涉及的重要内部函数及功能 requestRadioPower

开启通讯模块 requestQueryNetworkSelectionMode 查询网络模式 requestGetCurrentCalls

获取当前通话 requestDial

请求呼叫 requestWriteSmsToSim

写入短信至SIM卡 requestHangup

挂断电话 requestSignalStrength

获取信号强度 requestRegistrationState

获取卡注册状态 requestOperator

获取运营商名称 requestSendSMS

请求发送短信 requestSetupDataCall

拨号上网 requestSMSAcknowledge

短信回报

requestEnterSimPin

请求输入SIM PIN码 requestSendUSSD

请求USSD业务  本文件提供给ril.cpp调用的外部接口 RIL_Init

RIL初始化 onRequest

AT请求指令接口(异步方式)

getVersion

获取RIL版本号,当前为\"android reference-ril 1.0\" onUnsolicited

AT请求指令接口(同步方式)

2)ril.cpp 该文件主要提供ril.java调用接口,实现RIL的JNI调用方式、RIL Event管理机制  实现了供上层调用的接口 typedef struct {

int requestNumber;

void (*dispatchFunction) (Parcel &p, struct RequestInfo *pRI);

int(*responseFunction) (Parcel &p, void *response, size_t responselen); } CommandInfo; 具体执行的操作可以看头文件ril_commands.h 举一个例子:

拨打电话,对应的requestNumber为RIL_REQUEST_DIAL,对应的dispatchFunction为dispatchDial,对应的responseFunction为responseFunction。  RIL Event管理

与ril_event.cpp的Event接口配合实现RIL Event管理 RIL_startEventLoop rilEventAddWakeup eventLoop ril_event_init ril_event_set ril_event_add ril_event_del 4) rild.c rild的主要初始化工作都在main函数中进行。

5、RIL JNI上层对外接口

SetOnNITZTime

getIccCardStatus

supplyIccPin

supplyIccPuk

supplyIccPin2

supplyIccPuk2

changeIccPin

changeIccPin2

getCurrentCalls

getPDPContextList dial

getIMSI

getIMEI

getIMEISV

hangupConnection

acceptCall

rejectCall

getLastCallFailCause getLastPdpFailCause getLastDataCallFailCause setMute

getMute

getSignalStrength

getRegistrationState getGPRSRegistrationState getOperator

设置网络身份和时区 获取SIM卡状态 输入PIN码 输入PUK码 输入PIN2码 输入PUK2码 修改PIN码 修改PIN2码 获取当前通话 获取PDP列表 拨号

获取IMSI 获取IMEI 获取IMEISV 挂断电话 接听电话 电话拒接

获取Call失败错误码 获取PDP失败错误码 获取拨号连接失败错误码

设置手机静音模式(静音/非静音) 获取手机静音模式(静音/非静音) 获取信号强度 获取卡注册状态 获取GPRS注册状态 获取运营商 sendDtmf

startDtmf stopDtmf sendSMS deleteSmsOnSim writeSmsToSim

发送DTMF Start DTMF Stop DTMF 发送短信

删除SIM卡短信 保存短信至SIM卡

6、RIL机制

RIL类有三个内部类:RILRequest、RILSender 、RILReceiver,这三个内部类共同实现上层的电信业务操作请求。

RILRequest,电信服务请求,上层应用通过该类与RIL JNI层进行消息的交互,同时RIL JNI层也通过该类与RIL底层进行消息的交互; RILSender,实现上层请求的命令发送 RILReceiver,负责接收底层的Response  以下是dial的RIL调用序列 上层调用dial 设置Request请求并发送至RILSender消息处理队列

RILRequest rr = RILRequest.obtain(RIL_REQUEST_DIAL, result); …

send(rr);  RILSender消息处理队列消息队列收到EVENT_SEND后往mSocket里边填写相应请求 RILD从mSocket中读取相应的请求为RIL_REQUEST_DIAL,并设置相应的event 执行dispatchDial  onRequest  requestDial发送AT指令

底层给予responseVoid的响应

RILD向mSocket填写相应的响应信息,并往RILReceiver消息队列发送  proceResponse proceSolicited responseVoid(JNI)

三、Telephony APP Framework概述

电信业务Framework涉及Call、SMS、SIM卡、PDP等,代码分为两个部分,一个是SDK API,一个是平台内部类,不对外开放。这部分简单的说,就是上层电信业务与底层RIL的中间层。

1、Internal Cla 1) ADN(Abbreviated Dialing Numbers,缩位拨号)相关的类 AdnRecord AdnRecordCache AdnRecordLoader 2) Call相关的类

Call:基类,GsmCall和CdmaCall都由该基类扩展实现 CdmaCal GsmCall

CallTracker:基类,GsmCallTracker和CdmaCallTracker都由这个基类进行扩展实现 GsmCallTracker: CdmaCallTracker PhoneBase:基类,CDMAPhone和GSMPhone都由这个基类扩展实现 CDMAPhone GSMPhone Phone:电话操作的一些接口 CallerInfo CallerInfoAsyncQuery CallForwardInfo:呼叫转移

CallFailCause:GSM Call失败错误码 CallFailCause:CDMA Call失败错误码 3) 数据连接相关类

DataConnection:基类,GsmDataConnection和CdmaDataConnection都基于该类扩展实现 GsmDataConnection CdmaDataConnection DataConnectionTracker:基类,CdmaDataConnectionTracker和GsmDataConnectionTracker都基于该类进行扩展实现 CdmaDataConnectionTracker GsmDataConnectionTracker 4) SIM卡相关类

IccCard:基类,RuimCard和SimCard都由该类进行扩展实现 RuimCard SimCard IccRecords:基类,RuimRecords和SIMRecords都基于该类进行扩展实现 RuimRecords SIMRecords IccProvider IccUtils 5) SMS相关类

SMSDispatcher:实现发送短信

SmsMeageBase:基类,SmsMeage由该类扩展实现 SmsMeage:短信PDU包解析

2、SDK API Cla 实现SDK API接口,具体架构见SDK API文档

四、Phone APP Android自带一个Phone App,实现了GSM/CDMA的通话功能,这部分代码放在\\packages\\apps\\Phone目录下。

Phone APP开机就运行了,可以从AndroidManifest.xml设置的应用权限看出来

。 开机做如下初始化工作:

A、初始化Telephony Framework B、Power、Ringer、Keyboard、状态栏、SIM卡的注册工作 C、CallNotifier、PhoneUtils初始化工作 具体可以参见onCreate Phone APP有如下几个重要的类

 PhoneApp requestWakeState:判断手机是否可休眠 wakeUpScreen:唤醒手机

PhoneAppBroadcastReceiver:内部类,可以实时监测手机的状态,飞行模式、蓝牙耳机等。  PhoneUtils 电话基本组件接口,实现电话的一些基本操作,如Dial、Answer、Hangup、Hold等 placeCall:电话呼出 Hangup:挂断电话 answerCall:接听电话

setMute/ setMuteInternal:静音 turnOnSpeaker:免提

showIncomingCallUi:显示来电界面  InCallScreen 该类实现通话界面流程,主要如下:

case R.id.menuAnswerAndHold,保持当前通话并接听: internalAnswerCall  PhoneUtils.answerCall(mPhone) case R.id.menuAnswerAndEnd,结束当前通话并接听:

internalAnswerAndEnd  PhoneUtils.answerAndEndActive(mPhone) case R.id.menuAnswer,接听:

internalAnswerCall  PhoneUtils.answerCall(mPhone) case R.id.menuIgnore,忽略:

internalHangupRingingCall  PhoneUtils.hangupRingingCall(mPhone) case R.id.menuSwapCalls,切换通话:

internalSwapCalls  PhoneUtils.switchHoldingAndActive(mPhone) case R.id.menuMergeCalls,合并通话: PhoneUtils.mergeCalls(mPhone) case R.id.menuManageConference,管理电话会议:

setInCallScreenMode(InCallScreenMode.MANAGE_CONFERENCE) case R.id.menuShowDialpad,显示拨号键盘: onShowHideDialpad  mDialer.openDialer(true) case R.id.menuSpeaker,免提:

onSpeakerClick  PhoneUtils.turnOnSpeaker case R.id.menuBluetooth,蓝牙: onBluetoothClick case R.id.menuMute,静音:

onMuteClick  PhoneUtils.setMute case R.id.menuHold,通话保持: onHoldClick case R.id.menuAddCall,添加通话: PhoneUtils.startNewCall(mPhone) case R.id.menuEndCall,结束通话: internalHangup  PhoneUtils.hangup(mPhone)  DTMFTwelveKeyDialer 该类实现DTMF proceDtmf:发送DTMF clearDigits:清除DTMF键码 startDtmfTone:播放DTMF Tone stopDtmfTone:停止播放DTMF Tone  CallNotifier 继承于Handler,用来实时监测通话状态并通知Phone Application,如PHONE_NEW_RINGING_CONNECTION(来电),PHONE_INCOMING_RING(来电响铃),PHONE_DISCONNECT(通话挂断),PHONE_BATTERY_LOW(电池电量低),具体相对应的处理可参见handleMeage  CallFeaturesSetting 实现通话设置,此外该类包含一个内部类VoiceMailProviderSettings用来实现语音信箱的设置

 CallCard/ InCallTouchUi 这两个类都是继承于FrameLayout,Phone用来实现通话自身的布局需求。

updatePhotoForCallState:更新替代图片(如果通话号码有设置特定代替图片的) updateDisplayForConference:通话UI更新(用于电话会议) updateDisplayForPerson:通话UI更新

getCallFailedString:获取通话失败错误字符串 displayOnHoldCallStatus:显示通话保持UI displayMainCallStatus:更新通话UI updateState:更新通话状态(供外部类调用)  BluetoothHandsfree/BluetoothHeadsetService 实现通话蓝牙耳机功能,其实现核心是BluetoothHeadsetService,在PhoneApp 创建的时候会启动它。BluetoothHeadsetService 通过接收底层蓝牙服务的状态消息来改变自身状态,同时它也会监听通话的状态变化。 onBluetoothEnabled:开启蓝牙设备 onBluetoothDisabled:关闭蓝牙设备 connectHeadset:连接蓝牙设备 audioOn:开启audio audioOff:关闭audio redial:通过蓝牙设备重播电话 updateBatteryState:更新电池强度 updateSignalState:更新信号强度

五、Android通话简单流程

1、拨打流程(以电话本入口为例)

进入电话本,以某个联系人发起呼叫,此时进入TwelveKeyDialer类的onClick函数case R.id.dialButton分支,启动OutgoingCallBroadcaster Intent intent = new Intent(Intent.ACTION_CALL_PRIVILEGED); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//以新的TASK启动 OutgoingCallBroadcaster发出Broadcast Announcement sendOrderedBroadcast(broadcastIntent, PERMISSION,

new OutgoingCallReceiver(), null, Activity.RESULT_OK, number, null); 收到Broadcast后,进入OutgoingCallReceiver中的doReceive启动InCallScreen 进入internalResolveIntent mInCallInitialStatus = internalResolveIntent(getIntent()); placeCall PhoneUtils.placeCallVia/ PhoneUtils.placeCall  Connection cn = phone.dial(number); Phone是Interface,所属的dial接口是在PhoneBase的子类GSMPhone中实现 进入GsmCallTracker类中的dial函数 mCT.dial(newDialString); 调用CommandsInterface的dial接口

cm.dial(pendingMO.addre, clirMode, obtainCompleteMeage()); CommandsInterface的dial接口是在RIL.java中实现的 调用JNI接口dial ……后续就是RIL JNI与libril的交互过程,见RIL机制

2、来电流程

CallNotifier的消息处理队列会收到PHONE_NEW_RINGING_CONNECTION onNewRingingConnection响铃或震动(来电自动接听也在里边处理) 显示来电界面InCallScreen PhoneUtils.showIncomingCallUi();

3、来电处理

 接听

internalAnswerCall

PhoneUtils.answerCall(mPhone)

关闭来电铃声等,进入接听流程phone.acceptCall() 调用GsmCallTracker的acceptCall mCT.acceptCall(); 调用CommandsInterface acceptCall 接口 cm.acceptCall(obtainCompleteMeage())

调用RIL JNI接口acceptCall向底层发送请求

……后续就是RIL JNI与libril的交互过程,见RIL机制  挂断

 internalHangup  PhoneUtils.hangup(mPhone)  调用GsmCallTracker的handup 调用CommandsInterface hangupConnection接口

cm.hangupConnection (conn.getGSMIndex(), obtainCompleteMeage()); 调用RIL JNI接口hangupConnection向底层发送挂断请求 ……后续就是RIL JNI与libril的交互过程,见RIL机制  通话保持恢复

PhoneUtils.switchHoldingAndActive(mPhone)  添加一个新通话,实现多方通话 PhoneUtils.startNewCall(mPhone)

Android_Phone源代码来电流程解读

***************************CallNotifier***************************

本类extends Handler并且implements CallerInfoAsyncQuery.OnQueryCompleteListener

电话状态改变之后本类会接到Meage,然后本Handler通过Meage的不同,进入不同的case:

然后调用不同的方法处理各种状态改变。

同时实现了OnQueryCompleteListener接口,当来电的时候会帮助执行查询操作,比如查询并调用

Ringer设置响铃方式。

当来电时,本类会接受到一个PHONE_NEW_RINGING_CONNECTION(Meage.what),然后调用对应的方法

onNewRingingConnection(),该方法又会调用startIncomingCallQuery()方法,该方法就查询用户

设置的铃声(可能是系统的,也可能是用户自定义的),如果查询完成则直接调用onQueryComplete().

假如执行超时的话,将会发送一个延时Meage,延时后将默认调用系统的铃声。

假如在延时发送Meage过程中Query已经完成,由于CallNotifier实现了OnQueryCopleteListener,

就会自动调用onQueryComplete()方法,该方法将会首先把可能存在的延时Meage给Remove,以防止

再次设置铃声。接着调用onCustomRingQueryComplete()方法。然后该方法里面会调用Ringer的ring()

方法启动响铃。

********************************Ringer*************************** Ringer的ring()方法会启动相应的响铃方式。

响铃之后将会又Meage发送,其内容为PHONE_STATE_CHANGED

*******************************InCallScreen**********************

InCallScreen将会接受到发送的PHONE_STATE_CHANGED消息,然后调用onPhoneStateChanged()方法

该方法将更新屏幕,CallNotifier的onCustomRingQueryComplete里也会通过PhoneUtils.showIncomingCallUi()

来启动InCallScreen屏幕。然后由InCallScreen处理,处理方式与前面打电话的大体一致,不过该类第一次调用时执行了

onCreate()方法,但是以后执行都是从onNewIntent()开始.

学习总结

学习总结

学习总结

学习总结

学习总结

学习总结

学习总结

学习总结

学习总结

学习总结

Android RIL&Call学习总结
《Android RIL&Call学习总结.doc》
将本文的Word文档下载到电脑,方便编辑。
推荐度:
点击下载文档
相关专题 androidril 学习总结
点击下载本文文档