本文紧接着上一篇文章《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);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

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

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

而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);}}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

在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) {// registerRecord 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);}}...}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

本文来自http://blog.csdn.net/linyongan ,转载请务必注明出处。


常见的注册监听和发通知的流程,以监听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 {
  • 1
  • 1

在它构造方法中:

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

所以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();}...}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

在这里就可以找到某个事件对应的方法是什么。

当然可以自己新增事件以及在IPhoneStateListener.aidl中新增对应的接口,再实现该接口就可以了。

原文地址: http://blog.csdn.net/linyongan/article/details/52126969

Android Telephony分析(五) ---- TelephonyRegistry详解相关推荐

  1. Android Telephony分析(三) ---- RILJ详解

    前言 本文主要讲解RILJ工作原理,以便更好地分析代码,分析业务的流程.  这里说的RILJ指的是RIL.java (frameworks\opt\telephony\src\java\com\And ...

  2. Android Telephony分析(二) ---- RegistrantList详解

    前言 本文主要讲解RegistrantList的原理,以及如何快速分析RegistrantList相关的代码流程.  在Telephony模块中,在RIL.Tracker(ServiceStateTr ...

  3. Android Telephony分析(四) ---- TelephonyManager详解

    前言 TelephonyManager主要提供Telephony相关信息的查询/修改功能,以及Phone状态监听功能,封装的方法主要是提供给APP上层使用.  TelephonyManager.jav ...

  4. Android Telephony分析(一) ---- Phone详解

    本文主要讲解Telephony中Phone相关的知识. 1. Android N中Phone的改变 Android 6.0时,Phone的继承关系: 在Android N中,Phone的继承关系: 变 ...

  5. Android Telephony分析(六) ---- 接口扩展(实践篇)

    本文将结合前面五篇文章所讲解的知识,综合起来,实现一个接口扩展的功能.  如果还没有阅读过前面五篇文章的内容,请先阅读:  <Android Telephony分析(一) - Phone详解 & ...

  6. Android Telephony分析(七) ---- 接口扩展(异步转同步)

    本文是基于上一篇<Android Telephony分析(六) -- 接口扩展(实践篇)>来写的.  上一篇介绍的接口扩展的方法需要实现两部分代码:  1. 从APP至RIL,发送请求:  ...

  7. android OKHttp的基本使用详解

    今天,简单讲讲Android里如何使用OKHttp. Android框架系列: 一.android EventBus的简单使用 二.android Glide简单使用 三.android OKHttp ...

  8. Android高效率编码-第三方SDK详解系列(一)——百度地图,绘制,覆盖物,导航,定位,细腻分解!...

    Android高效率编码-第三方SDK详解系列(一)--百度地图,绘制,覆盖物,导航,定位,细腻分解! 这是一个系列,但是我也不确定具体会更新多少期,最近很忙,主要还是效率的问题,所以一些有效的东西还 ...

  9. Android高效率编码-第三方SDK详解系列(一)——百度地图,绘制,覆盖物,导航,定位,细腻分解!

    Android高效率编码-第三方SDK详解系列(一)--百度地图,绘制,覆盖物,导航,定位,细腻分解! 这是一个系列,但是我也不确定具体会更新多少期,最近很忙,主要还是效率的问题,所以一些有效的东西还 ...

最新文章

  1. android源码编译 简书,android学习笔记之源码编译
  2. One-shot Learning with Memory-Augmented Neural Networks
  3. 超赞!这些 “电子” 艺术品,真绝了!
  4. BestCoder Round #91 1001 Lotus and Characters
  5. android录屏软件冲突,关于Android同时录制多个录像的问题
  6. 图解算法系列笔记(一)
  7. mac html编辑器 免费,Mac下 10 款最棒的编辑器
  8. spring注入bean的三种方法
  9. CDR 制作“决战高考”海报
  10. 成功的10000小时定律
  11. vw/vh:移动适配之vw/vh(使用方法)
  12. Cisco设备telnet登录设置
  13. powerquery分组_power query 如何累计求和?如何分组分条件?
  14. java使用三目运算符来判断成绩
  15. component has been registered but not used
  16. 基于python的灰色预测模型
  17. 亚马逊下架产品还能重新恢复吗?
  18. 软考信息系统监理师,2016年4月1日作业
  19. html5 first child,childfirst
  20. 关于soot静态分析的学习(一)

热门文章

  1. [转载]详细解说STL排序(sort)------这篇博文在一道题上救了我o_0
  2. stdout和stderr标准输出的区别
  3. linux常用指令笔记(1)
  4. ustc小道消息20211215
  5. 我们学习到底是为了什么,到底什么才是我们真正想要的
  6. 学长毕业日记 :本科毕业论文写成博士论文的神操作20160317
  7. 《algorithm-note》算法笔记中文版正式发布!
  8. VTK修炼之道79:交互与拾取_单位拾取
  9. C++list常用接口总结
  10. FFmpeg音视频入门-使用FFmpeg读取多媒体文件的信息C++代码实现+详解