日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

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

發布時間:2025/3/15 Android 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android Telephony分析(五) ---- TelephonyRegistry详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文緊接著上一篇文章《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详解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。