Android接电话流程、Phone来电过程、phone上层来电话解析 接通电话

时间:2022-08-29 21:57:09

   汇聚下,别人对来电的分析:

 

http://blog.csdn.net/ninedays/article/details/5969215

接电话的基本流程(java层):

首先,通过ddms拨打模拟器的电话,这样
在RIL.java的RILReceiver线程(run()函数中)当中接收到rild发来的incoming消息,接收线程将消息转给processResponse(p)进行处理,processResponse(p)又将消息转给processUnsolicited (p)处理,然后又转到          

         case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED:
                if (RILJ_LOGD) unsljLog(response);
                mCallStateRegistrants
                    .notifyRegistrants(new AsyncResult(null, null, null));
            break;
进行处理。这样消息就转到了mCallStateRegistrants(RegistrantList.java类中)的notifyRegistrants()函数进行处理了,接着转到internalNotifyRegistrants(ar.result, ar.exception);
消息继续上传到
            Registrant  r = (Registrant) registrants.get(i);
            r.internalNotifyRegistrant(result, exception);

    internalNotifyRegistrant的函数如下所示:

    internalNotifyRegistrant (Object result, Throwable exception)
    {
        Handler h = getHandler();

        if (h == null) {
            clear();
        } else {
            Message msg = Message.obtain();

            msg.what = what;
           
            msg.obj = new AsyncResult(userObj, result, exception);
           
            h.sendMessage(msg);
        }
    }

注意到消息是由Handler类型的h发出的。好了

我们来看Handler
在Handler中含有如下函数(只是没有什么实现而已)
handleMessage(Message msg)
这就好说了,接着我们看消息怎么上传的吧:
我们以GSM类型的Phone为例
找到CallTracker类,我们发现这个类是由Handler继承而来的,于是我们查看下其handleMessage(Message msg)函数,发现该函数还是没有什么实现(刚看了下原来该这是个抽象类,汗。。。)
不用着急,继续往下找,我们发现GsmCallTracker类是继承自CallTracker类的,看GsmCallTracker的名字,我们应该知道这个类是做什么用的了吧。
找到handleMessage(Message msg)函数,其中有如下语句:
            case EVENT_REPOLL_AFTER_DELAY:
            case EVENT_CALL_STATE_CHANGE:
                pollCallsWhenSafe();
            break;
注意第二个case语句,有电话来了,那么call的状态自然是要改变的,呵呵。
于是,转到 pollCallsWhenSafe()进行处理。

在CallTracker类中,pollCallsWhenSafe()函数是的实现如下

    protected void pollCallsWhenSafe() {
        needsPoll = true;

        if (checkNoOperationsPending()) {
            lastRelevantPoll = obtainMessage(EVENT_POLL_CALLS_RESULT);
            cm.getCurrentCalls(lastRelevantPoll);
        }
    }

其中 public CommandsInterface cm;
于是,转到RIL.java的

    public void
    getCurrentCalls (Message result) {
        RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_CURRENT_CALLS, result);

        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));

        send(rr);
    }
执行

这样,消息就往底层下发了,详细过程,我不解释,当消息处理完后,RIL.java的接收线程又会收到相应的消息

进入processSolicited (Parcel p)处理,然后消息进入GsmCallTracker类的
case:EVENT_POLL_CALLS_RESULT进行处理---->handlePollCalls(AsyncResult ar)---->消息经过发送和接收后进入
            case EVENT_REPOLL_AFTER_DELAY:
            case EVENT_CALL_STATE_CHANGE:
                pollCallsWhenSafe();
------>................消息太多,自己去跟踪吧
------>handlePollCalls((AsyncResult)msg.obj);
------>pollCallsWhenSafe();
接通电话,则进入下面的函数执行
------>operationComplete();
进入App层处理,找下CallNotifier.java的handleMessage()函数,在接下来的过程当中,就比较好跟踪了,我也懒得写了。

以下部分为查看日志得到的过程,可能存在错误


CallNotifier.java收到incoming消息后转到handleMessage()进行处理;handleMessage()将incoming消息传给onNewRingingConnection()函数进行处理;在onNewRingingConnection()函数中首先建立ringing连接,获取Call.State状态为INCOMING,然后通过PhoneApp的requestWakeState()函数唤起相应的状态(PARTIAL);然后移除PHONE_AUTO_ANSWER消息;接着执行startIncomingCallQuery(c);在函数startIncomingCallQuery中通过PhoneUtils的startGetCallerInfo()函数获取Caller的相关信息;这样就完成了ringing的连接;同时就完成了incoming状态的一个改变,进一步在CallNotifier的hangdleMessage中调用onPhoneStateChanged()函数处理相关状态的改变(包括通知PhoneApp状态改变,通知InCallScreen状态改变)。InCallScreen受到状态改变的消息后在handleMessage中对之进行处理,即要调用InCallScreen的onPhoneStateChanged()函数进行处理。回到CallNotifier.java中,当handleMessage()处理onCustomRingQueryComplete(),在该函数中会调用Ringer.java的响铃函数进行铃声通知ring(),接着再调用PhoneUtils.showIncomingCallUi();显示UI(通过调用PhoneApp类的displayCallScreen()函数)。下一步,如果接通电话,则走如下流程:
首先更新UI显示(调用CallCard.java的相关函数),然后进入InCallScreen的消息处理,接着进入PhoneUtils的answerCall()函数,在此函数中,会首先通过
PhoneApp.getInstance().getRinger().stopRing();停止响铃,然后更新UI页面。

 

http://www.eoeandroid.com/thread-39731-1-1.html

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

本类extends Handler并且implements CallerInfoAsyncQuery.OnQueryCompleteListener

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

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

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

   Ringer设置响铃方式。

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

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

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

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

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

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

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

   方法启动响铃。

********************************Ringer***************************

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

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

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

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

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

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

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