Android Telephony分析(五)--- TelephonyRegistry 详解

原文出处:http://blog.csdn.net/linyongan/article/details/52126969


本文紧接着上一篇文章Android Telephony分析(四)--- TelephonyManager 详解 的1.4小节。
从TelephonyRegistry的大部分方法中:
这里写图片描述
可以看出TelephonyRegistry主要的功能是上报消息,有两种方式:
1. 通过notifyXXX方法。
2. 通过发送broadcast。

至于发广播没什么好说的了,我们看看notifyXXX方法吧,以notifyCallStateForPhoneId()方法为例

    public void notifyCallStateForPhoneId(int phoneId, int subId, int state,
                String incomingNumber) {
        //先检测权限
        if (!checkNotifyPermission("notifyCallState()")) {
            return;
        }
        //1.mRecords是什么?
        synchronized (mRecords) {
            int phoneId = SubscriptionManager.getPhoneId(subId);
            if (validatePhoneId(phoneId)) {
                mCallState[phoneId] = state;
                mCallIncomingNumber[phoneId] = incomingNumber;
                //遍历mRecords列表
                for (Record r : mRecords) {
                    //取出注册监听"LISTEN_CALL_STATE"这种事件的Record对象
                    if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_CALL_STATE) &&
                            (r.subId == subId) &&
                            (r.subId != SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) {
                        try {
                            String incomingNumberOrEmpty = getCallIncomingNumber(r, phoneId);
                            //2.Record.callback又是什么?
                            r.callback.onCallStateChanged(state, incomingNumberOrEmpty);
                        } catch (RemoteException ex) {
                            mRemoveList.add(r.binder);
                        }
                    }
                }
            }
            handleRemoveListLocked();
        }
        //同时调用发广播的方法
        broadcastCallStateChanged(state, incomingNumber, phoneId, subId);
    }

通过初步分析notifyCallState()方法,你会发现有两个疑问:
1. mRecords是什么?
2. Record.callback又是什么?
好了,带着上面两种疑问,我们继续分析代码吧。

接着你会发现mRecords是由Record对象组成的List集合

    private final ArrayList<Record> mRecords = new ArrayList<Record>();

而Record是TelephonyRegistry中的内部类,TelephonyRegistry会把监听者的信息封装成一个Record对象,并且放进mRecords列表中管理。

class TelephonyRegistry extends ITelephonyRegistry.Stub {

    private static class Record {
        String callingPackage;
        IBinder binder;
        //Record.callback是实现了IPhoneStateListener接口的类,
        //也就是继承了或者重写了PhoneStateListener的类
        IPhoneStateListener callback;
        IOnSubscriptionsChangedListener onSubscriptionsChangedListenerCallback;
        int callerUserId;
        //存储用来记录监听的事件
        int events;
        int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
        int phoneId = SubscriptionManager.INVALID_PHONE_INDEX;
        boolean canReadPhoneState;
        boolean matchPhoneStateListenerEvent(int events) {
            return (callback != null) && ((events & this.events) != 0);
        }
        boolean matchOnSubscriptionsChangedListener() {
            return (onSubscriptionsChangedListenerCallback != null);
        }
    }

在TelephonyRegistry.Java的listen方法中,管理并维护着mRecords列表:

    public void listenForSubscriber(int subId, String pkgForDebug, IPhoneStateListener callback,
            int events, boolean notifyNow) {
        listen(pkgForDebug, callback, events, notifyNow, subId);
    }

    private void listen(String callingPackage, IPhoneStateListener callback, int events,
            boolean notifyNow, int subId) {
            ...
            synchronized (mRecords) {
                // register
                Record r;
                find_and_add: {
                    //得到监听者的信息
                    IBinder b = callback.asBinder();
                    //遍历mRecords列表
                    for (int i = 0; i < N; i++) {
                        r = mRecords.get(i);
                        if (b == r.binder) {
                            //退出循环
                            break find_and_add;
                        }
                    }
                    //如果监听者还没有被加到mRecords列表中
                    r = new Record();
                    r.binder = b;
                    //新建一个Record对象并且加入mRecords列表中
                    mRecords.add(r);
                    if (DBG) log("listen: add new record");
                }
                //存储监听者
                r.callback = callback;
                ...
                //存储监听者所监听的事件
                r.events = events;
                //如果需要现在发通知的话
                if (notifyNow && validatePhoneId(phoneId)) {
                    if ((events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) {
                        try {
                            //注册之后,马上通知一次监听者
                            r.callback.onServiceStateChanged(
                                    new ServiceState(mServiceState[phoneId]));
                        } catch (RemoteException ex) {
                            remove(r.binder);
                        }
                    }
                ...
    }


常见的注册监听和发通知的流程,以监听Call状态变化为例:
这里写图片描述
总体看分成3步:
1. 根据需要监听的事件,重写PhoneStateListener中对应的方法,如果需要监听LISTEN_CALL_STATE,那么需要重写 onCallStateChanged()方法;如果需要监听LISTEN_SERVICE_STATE,则需要重写onServiceStateChanged()方法。(步骤1)
2. 调用TelephonyManager的listen()方法,传递PhoneStateListener对象和events。到这里监听的操作一直执行到步骤4就结束了。
3. 当有Call状态变化消息上来时,通知上报的路径:
RILJ—>CallTracker—>Phone—>DefaultPhoneNotifier—>TelephonyRegistry—>监听者
最后也是来到监听者重写的PhoneStateListener的那个方法中,整个过程也是一个回调。

其他需要说明的是:
1. DefaultPhoneNotifier是TelephonyRegistry最常用的客户端,它继承自

public class DefaultPhoneNotifier implements PhoneNotifier {

在它构造方法中:

    protected DefaultPhoneNotifier() {
        //通过ServiceManager得到了TelephonyRegistry的代理对象
        mRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
                    "telephony.registry"));
    }

所以DefaultPhoneNotifier中大部分方法都依靠TelephonyRegistry对象来实现。

2 . 如何知道我需要监听的事件以及对应要重写的方法?
所有的可以监听的事件都定义在PhoneStateListener.java (frameworks\base\telephony\java\Android\telephony)中,
这里写图片描述
需要重写的方法,初始都定义在IPhoneStateListener.aidl(frameworks/base/telephony/java/com/android/internal/telephony)中
这里写图片描述
接着由PhoneStateListener初步重写了IPhoneStateListener.aidl接口中的方法:

    /**
     * The callback methods need to be called on the handler thread where
     * this object was created.  If the binder did that for us it'd be nice.
     */
    IPhoneStateListener callback = new IPhoneStateListener.Stub() {
        public void onServiceStateChanged(ServiceState serviceState) {
            Message.obtain(mHandler, LISTEN_SERVICE_STATE, 0, 0, serviceState).sendToTarget();
        }
        ...
    }

在这里就可以找到某个事件对应的方法是什么。
当然可以自己新增事件以及在IPhoneStateListener.aidl中新增对应的接口,再实现该接口就可以了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值