当前位置:首页 >> 信息与通信 >>

android通话流程浅析RIL层


拨出电话流程: 1 在系统源码这个路径下/packages/apps/Phone/src/com/android/phone/DialtactsActivity.java contacts 的 androidmanifest.xml android:process="android.process.acore"说明此应用程序运行 在 acore 进程中。Dia

ltactsActivity 的 intent-filter 的 action 属性设置为 main,catelog 属性设 置为 launcher,所以此 activity 能出现, 首先启动的就是这个 activity 在主菜单中,并且是点 击此应用程序的第一个界面。dialtactsactivity 包含四个 tab,分别由 TwelveKeyDialer、 RecentCallsListActivity , 两 个 activity-alias DialtactsContactsEntryActivity 和 DialtactsFavoritesEntryActivity 分别表示联系人和收藏 tab,但是正真的联系人列表和收藏是 由 ContactsListActivity 负责。 2 进入 TwelveKeyDialer OnClick 方法,按住的按钮 id 为: R.id.digits,执行 placecall() Intent intent = new Intent(Intent.ACTION_CALL_PRIVILEGED, Uri.fromParts("tel", number, null)); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); 3、 intert.ACTION_CALL_PRIVILEGED 实际字符串为 android.intent.action.CALL_PRIVILEGED, 通过查 找知道了 packegs/phone 下面的 androidmanifest.xml 中 PrivilegedOutgoingCallBroadcaster activity-alias 设置了 intent-filter,所以需要找到其 targetactivity 为 OutgoingCallBroadcaster。 所以进入 OutgoingCallBroadcaster 的 onCreate() //如果为紧急号码马上启动 intent.setClass(this, InCallScreen.class); startActivity(intent); Intent broadcastIntent = new Intent(Intent.ACTION_NEW_OUTGOING_CALL); if (number != null) broadcastIntent.putExtra(Intent.EXTRA_PHONE_NUMBER, number); broadcastIntent.putExtra(EXTRA_ALREADY_CALLED, callNow); broadcastIntent.putExtra(EXTRA_ORIGINAL_URI, intent.getData().toString()); if (LOGV) Log.v(TAG, "Broadcasting intent " + broadcastIntent + "."); sendOrderedBroadcast(broadcastIntent, PERMISSION, null, null, Activity.RESULT_OK, number, null); 4 、 Intent.ACTION_NEW_OUTGOING_CALL 实 际 字 符 android.intent.action.NEW_OUTGOING_CALL,通过查找知道了 packegs/phone





下面的 androidmanifest.xml 中 OutgoingCallReceiver Receiver 接收此 intent 消息。找到
1 / 22

OutgoingCallReceiver,执行 onReceive()函数 Intent newIntent = new Intent(Intent.ACTION_CALL, uri); newIntent.putExtra(Intent.EXTRA_PHONE_NUMBER, number); newIntent.setClass(context, InCallScreen.class); newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 5、请求拨号的 java 部分流程 onCreate(第一次)/onNewIntent(非第一次) internalResolveIntent placeCall(intent); PhoneUtils.placeCall(mPhone, number, intent.getData()); phone.dial(number); mCT.dial(newDialString); dial(dialString, CommandsInterface.CLIR_DEFAULT); cm.dial(pendingMO.address, clirMode, obtainCompleteMessage());//obtainCompleteMessage(EVENT_OPERATION_COMPLETE); send(rr); msg = mSender.obtainMessage(EVENT_SEND, rr); acquireWakeLock(); msg.sendToTarget(); RILSender.handleMessage() case EVENT_SEND: ...

2 / 22

s.getOutputStream().write(dataLength); s.getOutputStream().write(data);//从这里流程跑到下面 ril.cpp 中监听 部份 6、请求拨号的 c/c++部分流程 6.1、初始化事件循环,启动串口监听,注册 socket 监听。 rild.c->main() (1)、RIL_startEventLoop //建立事件循环线程 ret = pthread_create(&s_tid_dispatch, &attr, eventLoop, NULL); //注册进程唤醒事件回调 ril_event_set (&s_wakeupfd_event, s_fdWakeupRead, true, processWakeupCallback, NULL); rilEventAddWakeup (&s_wakeupfd_event); //建立事件循环 ril_event_loop for (;;) { ... n = select(nfds, &rfds, NULL, NULL, ptv); // Check for timeouts processTimeouts(); // Check for read-ready processReadReadies(&rfds, n); // Fire away
3 / 22

firePending(); } (2) 、 funcs = rilInit(&s_rilEnv, argc, rilArgv);// 实 际 是 通 过 动 态 加 载 动 态 库 的 方 式 执 行 reference-ril.c 中的 RIL_Init //单独启动一个线程读取串口数据 ret = pthread_create(&s_tid_mainloop, &attr, mainLoop, NULL); fd = open (s_device_path, O_RDWR); ret = at_open(fd, onUnsolicited); ret = pthread_create(&s_tid_reader, &attr, readerLoop, &attr); RIL_requestTimedCallback(initializeCallback, NULL, &TIMEVAL_0);

在 initializeCallback 中执行的程序: setRadioState (RADIO_STATE_OFF); at_handshake(); /* note: we don't check errors here. Everything important will be handled in onATTimeout and onATReaderClosed */ /* atchannel is tolerant of echo but it must */ /* have verbose result codes */ at_send_command("ATE0Q0V1", NULL); /* No auto-answer */ at_send_command("ATS0=0", NULL); ...

4 / 22

//注册 rild socket 端口事件监听到事件循环中 (3)、RIL_register(funcs); s_fdListen = android_get_control_socket(SOCKET_NAME_RIL); ret = listen(s_fdListen, 4); ril_event_set (&s_listen_event, s_fdListen, false, listenCallback, NULL);//将此端口加入事件 select 队列 rilEventAddWakeup (&s_listen_event);

如果 rild socket 端口有数据来了将执行 listencallback 函数 listencallback //为此客户端连接创建新的监听句柄,s_fdListen 继续监听其他客户端的连接。 s_fdCommand = accept(s_fdListen, (sockaddr *) &peeraddr, &socklen); ril_event_set (&s_commands_event, s_fdCommand, 1, processCommandsCallback, p_rs);//将此端口加入事件 select 队列 rilEventAddWakeup (&s_commands_event); 6.2、socket 监听,收到 dial 的 socket 请求 processCommandsCallback //读数据到 p_record 中 ret = record_stream_get_next(p_rs, &p_record, &recordlen); processCommandBuffer(p_record, recordlen); p.setData((uint8_t *) buffer, buflen);
5 / 22

// status checked at end status = p.readInt32(&request); status = p.readInt32 (&token);//请求队列中的序号 pRI = (RequestInfo *)calloc(1, sizeof(RequestInfo)); pRI->token = token;

/* 包含#include "ril_commands.h"语句,结构体如下: typedef struct { int requestNumber; void (*dispatchFunction) (Parcel &p, struct RequestInfo *pRI); int(*responseFunction) (Parcel &p, void *response, size_t responselen); } CommandInfo; */ pRI->pCI = &(s_commands[request]); pRI->p_next = s_pendingRequests; s_pendingRequests = pRI; pRI->pCI->dispatchFunction(p, pRI);

//假设是接收了 dial 指令,pRI->PCI->dispatchFunction(p,pRI),调用 dispatchDial (p,pRI) dispatchDial (p,pRI) s_callbacks.onRequest(pRI->pCI->requestNumber, &dial, sizeof(dial), pRI);
6 / 22

in reference-ril.c onRequest() ... switch (request) { case RIL_REQUEST_DIAL: requestDial(data, datalen, t); asprintf(&cmd, "ATD%s%s;", p_dial->address, clir); ret = at_send_command(cmd, NULL); err = at_send_command_full (command, NO_RESULT, NULL, NULL, 0, pp_outResponse); err = at_send_command_full_nolock(command, smspdu,timeoutMsec, sponse); err = writeline (command); //此处等待,直到收到成功应答或失败的应答,如:ok,connect,error cme 等 err = pthread_cond_wait(&s_commandcond, &s_commandmutex); waiting.... waiting.... type, responsePrefix,

/* success or failure is ignored by the upper layer here. it will call GET_CURRENT_CALLS and determine success that way */ RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0); p.writeInt32 (RESPONSE_SOLICITED); p.writeInt32 (pRI->token);

7 / 22

errorOffset = p.dataPosition(); p.writeInt32 (e); if (e == RIL_E_SUCCESS) { /* process response on success */ ret = pRI->pCI->responseFunction(p, response, responselen); if (ret != 0) { p.setDataPosition(errorOffset); p.writeInt32 (ret); } } sendResponse(p); sendResponseRaw(p.data(), p.dataSize()); blockingWrite(fd, (void *)&header, sizeof(header)); blockingWrite(fd, data, dataSize);

6.4、串口监听收到 atd 命令的应答"OK"或"no carrier"等 readerLoop() line = readline(); processLine(line); handleFinalResponse(line); pthread_cond_signal(&s_commandcond);// 至 此 , 前 面 的 等 待 结 束 , 接 着 执 行 RIL_onRequestComplete 函数

8 / 22

6.5、java 层收到应答后的处理,以 dial 为例子. ril.java->RILReceiver.run() for(;;) { ... length = readRilMessage(is, buffer); p = Parcel.obtain(); p.unmarshall(buffer, 0, length); p.setDataPosition(0); processResponse(p); type = p.readInt(); if (type == RESPONSE_SOLICITED) { processSolicited (p); serial = p.readInt(); rr = findAndRemoveRequestFromList(serial); rr.mResult.sendToTarget(); ...... }

CallTracker.java->handleMessage (Message msg) switch (msg.what) { case EVENT_OPERATION_COMPLETE:
9 / 22

ar = (AsyncResult)msg.obj; operationComplete(); cm.getCurrentCalls(lastRelevantPoll); 第二部分:unsolicited 消息从 modem 上报到 java 的流程。 c++部份 readerLoop() line = readline(); processLine(line); handleUnsolicited(line); if (s_unsolHandler != NULL) { s_unsolHandler (line1, line2);//实际执行的是 void onUnsolicited (const char *s, const char *sms_pdu) if (strStartsWith(s,"+CRING:") || strStartsWith(s,"RING") || strStartsWith(s,"NO CARRIER") || strStartsWith(s,"+CCWA") ) RIL_onUnsolicitedResponse (RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED, NULL, 0); p.writeInt32 (RESPONSE_UNSOLICITED); p.writeInt32 (unsolResponse); ret datalen); ret = sendResponse(p);
10 / 22

=

s_unsolResponses[unsolResponseIndex].responseFunction(p,

data,

sendResponseRaw(p.data(), p.dataSize()); ret = blockingWrite(fd, (void *)&header, sizeof(header)); blockingWrite(fd, data, dataSize);

java 部份 ril.java->RILReceiver.run() for(;;) { ... length = readRilMessage(is, buffer); p = Parcel.obtain(); p.unmarshall(buffer, 0, length); p.setDataPosition(0); processResponse(p); processUnsolicited (p); response = p.readInt(); switch(response) { ... case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: ret = responseVoid(p); break; ... } switch(response) {
11 / 22

case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: if (RILJ_LOGD) unsljLog(response);

mCallStateRegistrants .notifyRegistrants(new AsyncResult(null, null, null)); ... }

第三部分、 第四部分: 猫相关的各种状态的监听和通知机制/通话相关的图标变换的工作原 理。 网络状态,edge,gprs 图标的处理 a、注册监听部分 ==>SystemServer.java init2() Thread thr = new ServerThread(); thr.setName("android.server.ServerThread"); thr.start(); ServerThread.run() com.android.server.status.StatusBarPolicy.installIcons(context, statusBar); sInstance = new StatusBarPolicy(context, service); // phone_signal mPhone = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE); mPhoneData = IconData.makeIcon("phone_signal", null, com.android.internal.R.drawable.stat_sys_signal_null, 0, 0); mPhoneIcon = service.addIcon(mPhoneData, null); // register for phone state notifications. ((TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE)) .listen(mPhoneStateListener, PhoneStateListener.LISTEN_SERVICE_STATE | PhoneStateListener.LISTEN_SIGNAL_STRENGTH | PhoneStateListener.LISTEN_CALL_STATE | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE | PhoneStateListener.LISTEN_DATA_ACTIVITY); // 实 际 是 调 用 的 是 TelephonyRegistry.listen , 此 listen 函 数 会 将 Iphonestatelistener 添加到对应的的 handler 数组中,到时来了事件会轮询回调。

12 / 22

// data_connection mDataData = IconData.makeIcon("data_connection", null, com.android.internal.R.drawable.stat_sys_data_connected_g, 0, 0); mDataIcon = service.addIcon(mDataData, null); service.setIconVisibility(mDataIcon, false); b、事件通知部分 ==>PhoneFactory.java makeDefaultPhones() sPhoneNotifier = new DefaultPhoneNotifier(); useNewRIL(context); phone = new GSMPhone(context, new RIL(context), sPhoneNotifier); for example ==>DataConnectionTracker.java notifyDefaultData(String reason) phone.notifyDataConnection(reason); mNotifier.notifyDataConnection(this, reason); ==>DefaultPhoneNotifier.java mRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService( "telephony.registry")); mRegistry.notifyDataConnection(convertDataState(sender.getDataConnectionState()), sender.isDataConnectivityPossible(), reason, sender.getActiveApn(), sender.getInterfaceName(null));

第五部分:gprs 拨号上网的通路原理。 上层 java 程序调用 gprs 流程: =>PhoneApp.java onCreate() PhoneFactory.makeDefaultPhones(this); phone = new GSMPhone(context, new SimulatedCommands(), sPhoneNotifier); mDataConnection = new DataConnectionTracker (this); createAllPdpList();//建立缺省 pdpconnection pdp = new PdpConnection(phone); dataLink = new PppLink(phone.mDataConnection); dataLink.setOnLinkChange(this, EVENT_LINK_STATE_CHANGED, null); //某个条件触发执行 trySetupData(String reason) setupData(reason); pdp = findFreePdp(); Message msg = obtainMessage(); msg.what = EVENT_DATA_SETUP_COMPLETE; msg.obj = reason;
13 / 22

pdp.connect(apn, msg); phone.mCM.setupDefaultPDP(apn.apn, apn.user, apn.password, obtainMessage(EVENT_SETUP_PDP_DONE)); //收到 EVENT_SETUP_PDP_DONE 消息 =>pdpconnection.java handleMessage() case EVENT_SETUP_PDP_DONE: dataLink.connect();//dataLink 是 pppLink.java SystemService.start(SERVICE_PPPD_GPRS);//启动 pppd_grps 服务 poll.what = EVENT_POLL_DATA_CONNECTION; sendMessageDelayed(poll, POLL_SYSFS_MILLIS);//启动轮询,看是否成功 连接 gprs checkPPP()//每隔 5 秒轮询,看是否连接成功,或断开 //如果已经连接 mLinkChangeRegistrant.notifyResult(LinkState.LINK_UP); //执行到 pdpconnection.handleMessage() case EVENT_LINK_STATE_CHANGED onLinkStateChanged(ls); case LINK_UP: notifySuccess(onConnectCompleted); onCompleted.sendToTarget(); //执行 dataConnectionTracker.java 的 handleMessage() case EVENT_DATA_SETUP_COMPLETE notifyDefaultData(reason); setupDnsProperties(); setState(State.CONNECTED); phone.notifyDataConnection(reason); startNetStatPoll(); resetPollStats(); 1、读取发送出去的包数和接受到的包数 2、如果发送的数据包且没有收到应答包数 n 大于等于看门狗追 踪的限定包数。 2.1、开始轮询 pdp context list,尝试恢复网络连接 2.2、如果轮询 24 次后还没有联通网络则停止网络状态轮询,进 行一次 ping 实验。 2.2.1、如果 ping 成功则,重新进行网络状态轮询,否则发送 EVENT_START_RECOVERY 事件。 // reset reconnect timer nextReconnectDelay = RECONNECT_DELAY_INITIAL_MILLIS;

14 / 22

着重 c++部分代码的角度分析 =>DataConnectionTracker.java trySetupData(String reason) setupData(reason); =>PdpConnection.java pdp.connect(apn, msg); =>RIL.JAVA phone.mCM.setupDefaultPDP(apn.apn, apn.user, apn.password, obtainMessage(EVENT_SETUP_PDP_DONE)); send(rr); //send socket to RIL //enter c++ layer =>ril.cpp processCommandsCallback (int fd, short flags, void *param) processCommandBuffer(p_record, recordlen); status = p.readInt32(&request); pRI->pCI = &(s_commands[request]); pRI->pCI->dispatchFunction(p, pRI); dispatchStrings(); s_callbacks.onRequest(pRI->pCI->requestNumber, pStrings, datalen, pRI); =>reference-ril.c onRequest(); requestSetupDefaultPDP(data, datalen, t); err = write_at_to_data_channel("ATD*99***1#",1); //after a while.get "connect" from data channel,so need to send socket message to java layer. p.writeInt32 (RESPONSE_SOLICITED); p.writeInt32 (pRI->token);//the serial No in the request list. errorOffset = p.dataPosition(); p.writeInt32 (e); if (e == RIL_E_SUCCESS) { /* process response on success */ ret = pRI->pCI->responseFunction(p, response, responselen); /* if an error occurred, rewind and mark it */ if (ret != 0) { p.setDataPosition(errorOffset); p.writeInt32 (ret); } } sendResponse(p); sendResponseRaw(p.data(), p.dataSize());
15 / 22

ret = blockingWrite(fd, (void *)&header, sizeof(header)); blockingWrite(fd, data, dataSize); =>RIL.JAVA RILReceiver.run(); length = readRilMessage(is, buffer); p = Parcel.obtain(); p.unmarshall(buffer, 0, length); p.setDataPosition(0); processResponse(p); processSolicited (p); serial = p.readInt(); error = p.readInt(); rr = findAndRemoveRequestFromList(serial); ret = responseStrings(p); if (rr.mResult != null) { AsyncResult.forMessage(rr.mResult, ret, null); rr.mResult.sendToTarget(); } =>pdpConnection.java handleMessage() case EVENT_SETUP_PDP_DONE: ... dataLink.connect(); =>pppLink.java SystemProperties.set(PROPERTY_PPPD_EXIT_CODE, ""); SystemService.start(SERVICE_PPPD_GPRS);//启动 pppd_grps 服务 poll.what = EVENT_POLL_DATA_CONNECTION; sendMessageDelayed(poll, POLL_SYSFS_MILLIS); dataConnection.state = State.CONNECTING; handleMessage() case EVENT_POLL_DATA_CONNECTION checkPPP(); if (ArrayUtils.equals(mCheckPPPBuffer, UP_ASCII_STRING, UP_ASCII_STRING.length) || ArrayUtils.equals(mCheckPPPBuffer, UNKNOWN_ASCII_STRING, UNKNOWN_ASCII_STRING.length) && dataConnection.state == State.CONNECTING) if (mLinkChangeRegistrant != null) { mLinkChangeRegistrant.notifyResult(LinkState.LINK_UP); =>pdpConnection.java handleMessage()
16 / 22

case EVENT_LINK_STATE_CHANGED: DataLink.LinkState ls = (DataLink.LinkState) ar.result; onLinkStateChanged(ls); case LINK_UP: notifySuccess(onConnectCompleted); AsyncResult.forMessage(onCompleted); onCompleted.sendToTarget(); =>DataConnectionTracker.java handleMessage() case EVENT_DATA_SETUP_COMPLETE: ... SystemProperties.set("gsm.defaultpdpcontext.active", "true"); notifyDefaultData(reason); setupDnsProperties();//设置 dns, gw, 我们的实现方 式是在 pppd 中设置的,不用 pppd 拨号的适用。 setState(State.CONNECTED); phone.notifyDataConnection(reason); mNotifier.notifyDataConnection(this, reason); =>DefaultPhoneNotifier.java //mRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService( "telephony.registry"));构造函数中初始化了 mRegistry mRegistry.notifyDataConnection(convertDataState(sender.getDataConnectionState()), sender.isDataConnectivityPossible(), reason, sender.getActiveApn(), sender.getInterfaceName(null)); startNetStatPoll(); } 第六部分:通话相关的语音通路切换原理、震动接口 6、语音通路 6.1、设置语音通路的路由

目前我们有两处处理: a、CallTracker.java 中的 handlePollCalls() 检测到+clcc 返回的电话列表中有状态为 DriverCall.State.ALERTING(表示拨打电话后, 对方
17 / 22

已经振铃),此时需要设置语音通路为 MODE_IN_CALL

b、PhoneUtils.java 中 setAudioMode()函数

c、调用通路分析 AudioManager audioManager = (AudioManager) context.getSystemService (Context.AUDIO_SERVICE); audioManager.setMode(mode); AudioManager.setMode(mode); AudioService.setMode(mode); AudioSystem.setMode(mode);(native function) android_media_AudioSystem.cpp==>android_media_AudioSystem_setMode() AudioSystem.cpp==>setMode() const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); binder = sm->getService(String16("media.audio_flinger")); ... gAudioFlinger = interface_cast<IAudioFlinger>(binder); ... return gAudioFlinger; 通 过 查 找 “ media.audio_flinger AudioFlinger.cpp==>instantiate()//Main_mediaserver.cpp 中被实例化。







defaultServiceManager()->addService(String16("media.audio_flinger"), AudioFlinger());

new

18 / 22

mAudioHardware = AudioHardwareInterface::create(); LOGV("Creating Vendor Specific AudioHardware"); hw = createAudioHardware(); return new AudioHardwareMarvell();

return af->setMode(mode); AudioHardwareLittle.cpp==>setMode(mode) doRouting(); enable_incall_headphone()//or others... system("alsactl -f /etc/alsactl/asound.state_none restore"); system("alsactl -f /etc/alsactl/asound.state_headset_r_s restore");

6.2、来电播放振铃,挂断或接听停止振铃。 ==>Phone.app onCreate() ringer = new Ringer(phone); Vibrator mVibrator = new Vibrator(); mService IHardwareService.Stub.asInterface(ServiceManager.getService("hardware")); notifier = new CallNotifier(this, phone, ringer, mBtHandsfree); mPhone.registerForIncomingRing(this, PHONE_INCOMING_RING, null); mPhone.registerForPhoneStateChanged(this, PHONE_STATE_CHANGED, null);
19 / 22

=

mPhone.registerForDisconnect(this, PHONE_DISCONNECT, null); ... case PHONE_INCOMING_RING: mRinger.ring(); mHardwareService.setAttentionLight(true); mVibratorThread.start(); while (mContinueVibrating) { mVibrator.vibrate(VIBRATE_LENGTH); SystemClock.sleep(VIBRATE_LENGTH + PAUSE_LENGTH); } ... makeLooper(); mRingHandler.sendEmptyMessage(PLAY_RING_ONCE); ... case PLAY_RING_ONCE: PhoneUtils.setAudioMode(mContext, AudioManager.MODE_RINGTONE); r.play(); ... case PHONE_DISCONNECT: case PHONE_STATE_CHANGED: ... mRinger.stopRing();
20 / 22

Message msg = mRingHandler.obtainMessage(STOP_RING); msg.obj = mRingtone; mRingHandler.sendMessage(msg);

case STOP_RING: r.stop(); getLooper().quit(); ... mVibrator.cancel(); 第七部分:通话相关的 notification 服务 7、通话相关的 notification 服务。 7.1、NotificationMgr ==>PhoneApp.java onCreate() NotificationMgr.init(this)//NotificationMgr.java//此类主要负责电话通知的具体表现(通知 和取消通知) ,未接图标、通话中、蓝牙激活中、保持中,静音、免提等。封装了简单的瞬 间显示文本消息的功能。 提供漫游数据连接禁止的通知封装和漫游数据连接允许时取消通知 sMe = new NotificationMgr(context); mNotificationMgr = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); mStatusBar = (StatusBarManager) context.getSystemService(Context.STATUS_BAR_SERVICE); //主要用于显示静音和 speaker 状态 的图表(在状态条右边显示) sMe.updateNotifications();//主要功能是: 1、查询是否有未读的未接听电话,并显示到状态栏图标,和通知列表
21 / 22

2、根据是否是电话状态,更新状态栏图表和通知列表(可能是激活,蓝牙, 保持等) 7.2、CallNotifier ==>PhoneApp.java onCreate() notifier = new CallNotifier(this, phone, ringer, mBtHandsfree);//此类主要是监听通话相关 的事件,然后进行例如来电播放铃声,震动。挂断、接听停止振铃等(调用 Ringer 类实现 此功能),根据不同的状态调用调用 NotificationMgr 进行具体的通知和取消通知。 第八部分: 通话相关的各种 server 电话通信相关的服务: (1)、从 ServiceManager 得到的: a、wifiService b、PhoneInterfaceManager c、PhoneSubInfo d、SimPhoneBookInterfaceManager e、SimSmsInterfaceManager f、TelephonyRegistry g、NetStatService h、ConnectivityService (2)、从 ApplicationContext 得到的: a、TelephonyManager

22 / 22


相关文章:
Android中RIL层详细分析
AndroidRIL层详细分析_计算机软件及应用_IT/计算机_专业资料。Android电话...代码中的重要模块列出进行分析, 并给出了相关的程序执行流程 介绍,以加深对模块...
Android RIL 流程分析
Android RIL 流程分析_IT/计算机_专业资料。本文以通话设置中的呼叫等待的设置为例,讲解RIL的流程。《Android-RIL 流程分析》 2010-12-20 呼叫等待的设置为例,讲...
Android通话过程分析
Android通话过程分析_IT/计算机_专业资料。Android 通话过程分析本文档主要对 android...4. DriverCall 是与 ril 层通信时的一个中间处理类,主要用来接收到 ril 的...
Android RIL层剖析(官方翻译)
Android RIL层剖析(官方翻译)_IT/计算机_专业资料。Android的无线接口层(RIL)提供...android通话流程浅析RIL... 22页 2下载券 Android 无线接口层(RIL... 28页 ...
Android的电话功能介绍——整个RIL文件夹的分析
Android电话功能介绍——整个RIL文件夹的分析_计算机软件及应用_IT/计算机_专业资料。Android电话功能介绍——整个 RIL 文件夹的分析 介绍本文档对 Android RIL...
Android_RIL层剖析(一家网站上找的)
(2) 下图表明 Android 系统中一个被动请求的电话过程:图 3 4 实现 RIL 为了...Android RIL 系统架构分析 2、Android RIL 参考实现分析 3、针对硬件平台实现...
adroid通信模块ril解析
(电话功能移植的两大部分:Modem 驱动和 ril 硬件抽象层,移植需要注意的问题是...在 android 之 Init 进程启动过 程源码分析一文中对 init 进程的启动流程进行...
Android RIL架构分析
Android RIL架构分析_计算机软件及应用_IT/计算机_专业...提供了 Telephony 服务和 Radio 硬件之间的抽象层。...四、Request 过程 初始化过程步骤 3 启动的 event...
Android RIL&Call学习总结
业务系统、 RIL、 Telephony APP Framework、 Phone APP、 Android 通话简单流程...RIL层代码分析 57页 免费 Android 中添加 AT 命令... 2页 免费 Telephony 代码...
Android RIL结构分析与移植
代码中的重要模块列出迚行分析,并给出了相关的程序执行流 程介绍,以加深对模块...1.Android RIL 概况: Android RIL 提供了无线硬件设备不电话服务乊间的抽象层...
更多相关标签: