Android非主用戶無線相關設置的顯示

需求

Android多用戶下,要讓每個用戶都能看到移動網絡相關設置(首先網絡類型/APN等)。

現狀

  • Android默認的多用戶實現中,只有主用戶(primary user)是可以看到的,如果新建一個另外的用戶,則沒有權限去看這些東西,參見WirelessSettings.java中的判斷(boolean isSecondaryUser = myUserId != UserHandle.USER_OWNER;如果是SecondaryUser,則不顯示相關設置)。
  • Primary user即user 0,是指開機進入的那個用戶,這個用戶的權限是最高的,framework,phone和其他的所有core service都是在這個用戶下創建和初始化的。
  • 無線相關(即phone對象和無線相關的服務),PhoneApp初始化的時候,會判斷是否在primary user(見下面),如果是user 0,那么會初始化這些對象;如果非0用戶,則會在此用戶創建一個新的空實現的Phone對象,因為在oncreate里面什么都沒做。所以不能在另外的用戶中直接調用phone相關的對象。
 if (UserHandle.myUserId() == 0) {
            // We are running as the primary user, so should bring up the
            // global phone state.
            mPhoneGlobals = new PhoneGlobals(this);
            mPhoneGlobals.onCreate();

            mTelephonyGlobals = new TelephonyGlobals(this);
            mTelephonyGlobals.onCreate();
  }  

方案

針對“現狀”中描述的情況,我們要在非primary user中顯示無線相關的信息,我們需要一個途徑來獲得我們需要的信息。有兩個解決辦法:

  • 放開PhoneApp對于用戶的限制,在非primary user中也初始化好phone相關對象。
  • 通過擴展primary user中的phone service來讓其他用戶獲得相關信息。

評估

方案1:在非primary user中也初始化phone相關對象。由于phone對象作為核心對象,從中初始化了很多其他相關的對象(例如sim卡,RIL等),這樣就涉及從上到下要全部打通才行,難度頗大。尤其是Android5.1-7.1中phone重構頗多,這個作為終極解決方案,但是在時間緊迫的前提下,我們只是簡單嘗試,沒事深入,感覺坑很多。后續會繼續探索,爭取在最新的安卓版本上搞定這個大事哈。感興趣的可以參考下面的鏈接,作者是在android4.2上做的,基本思路也是一致的。剩下的工作就是安卓版本差異上帶來的難度。
《android源碼探索----多用戶下phone進程問題》
http://blog.csdn.net/stephen8341/article/details/38079679

方案2:擴展“phone” service,讓其他user可以訪問到相關信息即可,畢竟只是setting展示,基本上需要的就是phone id/sub id之類的。這是個取巧的辦法,不完善,是在時間和項目的壓力下,妥協的方案。

方案2的實現

user 0中已經在開機的時候啟動的phone service(packages/services/Telephony/src/com/android/phone/PhoneInterfaceManager.java 的publish()函數),

private void publish() {
    if (DBG) log("publish: " + this);
    ServiceManager.addService("phone", this);
}

在其他user中需要使用的時候,通過如下方法調用

ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));

我們的做法就是擴展這個phone service,需要改動如下幾個文件:

  1. frameworks/base/telephony/java/com/android/internal/telephony/ITelephony.aidl 定義service提供的函數的aidl,把擴展的函數加進去
  2. packages/services/Telephony/src/com/android/phone/PhoneInterfaceManager.java 這個ITelephoy.aidl的實現
  3. 對于要回傳結果的場景,例如設置網絡,新建ITelephonyAdapter.aidl文件,定義回掉接口。并把這個aidl加入到framework/base下的Android.mk文件中,保證系統會編譯這個文件。
  4. 添加ITelephonyAdapter.aidl的實現文件TelephonyAdapter.java
  5. 剩下的就是判斷當前user,如果是非主用戶,通過service取相關信息,然后顯示相關UI。

總結

這里只是記錄一下解決問題的思路,思路對了,再慢也會完成相關功能。如果一開始就選了一個走不通的路,那么再努力也是徒勞。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,242評論 25 708
  • Jianwei's blog 首頁 分類 關于 歸檔 標簽 巧用Android多進程,微信,微博等主流App都在用...
    justCode_閱讀 5,962評論 1 23
  • 又一次夢到你了,你改了QQ頭像,名字,你的頭像是草書四年,因為你快畢業了。照片墻上的照片徹底換新,有你喜歡的動...
    軟仔的軟閱讀 153評論 0 0
  • 單身是個錯。90年的單身好像不老,今年26明年27就這樣時間過的很快,歲月總是這樣匆匆,忙碌的工作都來不及好好過好...
    好像音樂浮在水上閱讀 214評論 0 2
  • 距離上次更新這個系列,似乎已經是很久很久以前的事情了。 原因是,部門里新來了一個老板【為了區別稱呼,姑且叫他B S...
    瀾南潛石閱讀 976評論 5 1