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

歡迎訪問 生活随笔!

生活随笔

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

Android

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

發(fā)布時間:2025/3/15 Android 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android Telephony分析(六) ---- 接口扩展(实践篇) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文將結合前面五篇文章所講解的知識,綜合起來,實現一個接口擴展的功能。?
如果還沒有閱讀過前面五篇文章的內容,請先閱讀:?
《Android Telephony分析(一) — Phone詳解 》?
《Android Telephony分析(二) — RegistrantList詳解 》?
《Android Telephony分析(三) — RILJ詳解 》?
《Android Telephony分析(四) — TelephonyManager詳解 》?
《Android Telephony分析(五) — TelephonyRegistry詳解 》

至于接口擴展,也就是新增一個接口給APP調用,從APP至RIL,大體流程如下:

APPAPPTelephonyManagerTelephonyManagerPhonePhoneRILRIL發(fā)送Requestmodem處理返回結果返回結果

http://blog.csdn.net/linyongan?


1. 發(fā)送請求的實現

1.1 擴展BaseCommands接口

擴展BaseCommands接口主要為了在RIL.java 中實現向modem發(fā)送請求的方法。?
RILJ的繼承關系如下:?

所以要在RILJ中新增一個向modem發(fā)送Request的方法,需要擴展BaseCommands,再在RIL.java重寫該方法。?
在BaseCommands.java (frameworks\opt\telephony\src\java\com\Android\internal\telephony)添加一個方法:

public void setValueToModem(int input,Message response) {//這個方法為空,由讓子類按需要去重寫}
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

在RILConstants.java (frameworks\base\telephony\java\com\android\internal\telephony)中新增一個主動請求的消息:

//200這個數字需要根據實際項目進行修改int RIL_REQUEST_SET_VALUE = 200;
  • 1
  • 2
  • 1
  • 2

在RIL.java (frameworks\opt\telephony\src\java\com\android\internal\telephony)中新增發(fā)送請求的方法:

@Overridepublic void setValueToModem(int input,Message response) {//得到一個RILRequest對象RILRequest rr= RILRequest.obtain(RIL_REQUEST_SET_VALUE, response);//將APP傳遞過來的參數放到RILRequest對象中rr.mParcel.writeInt(input);//輸出關鍵logif (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)+ " " + input);send(rr);//for test//response.sendToTarget();}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

至于RILC的擴展省略,調試為了這個接口是否可用,故意寫了?
response.sendToTarget();這行代碼用于調試。

1.2 擴展PhoneInternalInterface接口

擴展PhoneInternalInterface接口主要為了封裝RILJ的方法,只要得到Phone的實例即可間接調用RILJ的方法。?
Phone的繼承關系如下:?
?
Phone.java是整個關系的中心樞紐,所以假如不用針對ImsPhone而走IMS流程的話,我們可以擴展PhoneInternalInterface接口,然后在Phone.java中具體實現即可。?
先在PhoneInternalInterface.java (frameworks\opt\telephony\src\java\com\android\internal\telephony)中新增一個接口:

void setValueToModem(int value);
  • 1
  • 2
  • 1
  • 2

在Phone.java (frameworks\opt\telephony\src\java\com\android\internal\telephony)統一實現該接口,Phone所有子類都使用這個方法:

@Overridepublic void setValueToModem(int input){//對于回調事件的處理,第2小節(jié)再講Message resp = obtainMessage(EVENT_SET_VALUE_DONE,0,0);//直接調用RILJ中的方法mCi.setValueToModem(input,resp);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

1.3 擴展ITelephony接口

擴展ITelephony接口主要是為了進一步封裝Phone對象中的方法,讓那些不能直接得到Phone對象的類也可以間接地調用Phone對象中的方法。?
先在ITelephony.aidl(frameworks\base\telephony\java\com\android\internal\telephony)中新增一個接口:

void setValueToModem(int input);
  • 1
  • 1

在PhoneInterfaceManager.java (packages\services\telephony\src\com\android\phone)中實現該接口:

@Overridepublic void setValueToModem(int input){try{//得到Phone對象Phone phone = PhoneFactory.getDefaultPhone();if(phone != null){phone.setValueToModem(input);}}catch(IllegalStateException e){}}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

由于PhoneInterfaceManager運行在Phone進程中,所以還需進一步封裝,讓不運行在Phone進程中的類也可以調用。?
在TelephonyManager.java (frameworks\base\telephony\java\android\telephony)中封裝Phone Service的方法:

/** @hide */public void setValueToModem(int input){try {//得到PhoneInterfaceManager的代理對象ITelephony telephony = getITelephony();if (telephony != null){telephony.setValueToModem(input);}} catch (RemoteException ex) {} catch (NullPointerException ex) {}}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

從RILJ—>Phone—>PhoneInterfaceManager—>TelephonyManager,經過一層層的封裝,APP終于可以通過TelephonyManager來間接調用RILJ中的方法了。?
整個過程的時序圖如下:?

2. 返回結果的實現

2.1 RILJ中的處理

在RILJ向modem發(fā)送請求之后,modem處理完會上報Solicited Response消息并且附帶著結果?
所以我們需要在RIL.java (frameworks\opt\telephony\src\java\com\android\internal\telephony)的processSolicited()方法中增加

case RIL_REQUEST_SET_VALUE: ret = responseInts(p); break;
  • 1
  • 1

在requestToString方法中增加

case RIL_REQUEST_SET_VALUE: return "RIL_REQUEST_SET_VALUE";
  • 1
  • 1

2.2 Phone中的處理

在《Android Telephony分析(三) — RILJ詳解 》的2.2.1小節(jié)中我們說過,接著會通過rr.mResult.sendToTarget();返回到創(chuàng)建Message對象的地方,也就是上面1.2小節(jié)說到的?
在Phone.java (frameworks\opt\telephony\src\java\com\android\internal\telephony)中:

@Overridepublic void setValueToModem(int input){//對于回調事件的處理,第2小節(jié)再講Message resp = obtainMessage(EVENT_SET_VALUE_DONE,0,0);//直接調用RILJ中的方法mCi.setValueToModem(input,resp);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

還需要對于回調事件進行處理,也就是先在Phone.java中定義EVENT_SET_VALUE_DONE消息:

//100這個數字需要根據實際項目進行修改protected static final int EVENT_SET_VALUE_DONE = 100;protected static final int EVENT_LAST =EVENT_SET_VALUE_DONE;
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

接著在handleMessage()方法中增加對EVENT_SET_VALUE_DONE的處理:

case EVENT_SET_VALUE_DONE://取出返回結果ar = (AsyncResult)msg.obj;String result = null;//如果返回結果不為空且沒有異常if (ar != null && ar.exception == null) {result = "success";}else{result = "fail";}//其實最偷懶的方式是直接在這里發(fā)廣播通知APP,//但是為了結合我們學過的知識,我還是通過PhoneNotifier來實現mNotifier.notifySetValueDone(result);break;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

2.3 擴展PhoneNotifier接口

擴展PhoneNotifier接口主要為了進一步上報消息并且附帶這結果。PhoneNotifier的常用子類是DefaultPhoneNotifier。?
先在PhoneNotifier.java (frameworks\opt\telephony\src\java\com\android\internal\telephony)中新增一個接口:

public void notifySetValueDone(String result);
  • 1
  • 1

接著在DefaultPhoneNotifier.java (frameworks\opt\telephony\src\java\com\android\internal\telephony)中實現該接口:

@Overridepublic void notifySetValueDone(String result){try {if (mRegistry != null) {//需要依賴TelephonyRegistry進一步上報通知mRegistry.notifySetValueDone(result);}} catch (RemoteException ex) {ex.printStackTrace();}}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

2.4 擴展ITelephonyRegistry接口

先在ITelephonyRegistry.aidl(frameworks\base\telephony\java\com\android\internal\telephony)中新增接口:

void notifySetValueDone(String result);
  • 1
  • 1

在TelephonyRegistry.java (frameworks\base\services\core\java\com\android\server)中實現該接口:

@Overridepublic void notifySetValueDone(String result){synchronized (mRecords) {for (Record r : mRecords) {//通知所有監(jiān)聽了LISTEN_SET_VALUE_DONE的類if((r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_SET_VALUE_DONE))){try {r.callback.onSetValueDone(result);} catch (RemoteException ex) {mRemoveList.add(r.binder);}}}handleRemoveListLocked();}}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

2.5 擴展IPhoneStateListener接口

擴展IPhoneStateListener接口主要為了新增一個可以監(jiān)聽的事件LISTEN_SET_VALUE_DONE。通過APP事先監(jiān)聽,當有該事件上報的時候,就會通知到APP。?
先IPhoneStateListener.aidl(frameworks/base/telephony/java/com/android/internal/telephony)中新增接口:

void onSetValueDone(String result);
  • 1
  • 1

在PhoneStateListener.java (frameworks\base\telephony\java\android\telephony)中新增可監(jiān)聽的事件,并且初步實現接口中的方法

/** @hide *///這個數字按項目實際需要修改public static final int LISTEN_SET_VALUE_DONE = 0x00800000;/** @hide*/public void onSetValueDone(String result){//由子類來重寫}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

在IPhoneStateListener callback = new IPhoneStateListener.Stub()中新增:

public void onSetValueDone(String result){Message.obtain(mHandler, LISTEN_SET_VALUE_DONE, 0, 0, result).sendToTarget();}
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

在handleMessage中新增:

case LISTEN_SET_VALUE_DONE://調用子類重寫的方法,也就是APP中的方法PhoneStateListener.this.onSetValueDone((String)msg.obj);break;
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

到這里,從RILJ—>Phone—>DefaultPhoneNotifier—>TelephonyRegistry—>APP,消息和結果就上報到APP了。?
整個過程的時序圖如下(步驟10~15):?

3. APP如何使用接口

在APP中可以這樣調用并調試接口:

//監(jiān)聽事件TelephonyManager.getDefault().listen(new PhoneStateListener(){@Overridepublic void onSetValueDone(String result){//對結果進行處理}}, PhoneStateListener.LISTEN_SET_VALUE_DONE);//發(fā)送請求TelephonyManager.getDefault().setValueToModem(1);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
原文地址: http://blog.csdn.net/linyongan/article/details/52151651

總結

以上是生活随笔為你收集整理的Android Telephony分析(六) ---- 接口扩展(实践篇)的全部內容,希望文章能夠幫你解決所遇到的問題。

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