android — sim/usim卡導連絡人

來源:互聯網
上載者:User

 from: http://blog.csdn.net/baimy1985/article/details/7820024

 

 

前面有一篇說了導卡上的資訊(android 資訊(mms)的故事(七)-- sim卡簡訊),sim卡上還有一類非常重要的資訊,就是卡上的連絡人。不知道大家注意到沒有,android手機,尤其是那些帶有電訊廠商標識的手機開機都比較慢,這個和開機導卡上的連絡人和資訊不無關係,電訊廠商是要求開機必須導卡的,不過要說句公道話,開機慢和導卡有關但也不能完全歸咎於它(android手機啟動時載入的東西本身也很多),當然如果你的手機開機不導卡也慢那肯定是另有原因的。 

        當然Android源碼開機是不導卡,如果我們需要查看卡上的連絡人需要手動匯入,從連絡人Contact應用ContactsListActivity.java這個類的menu菜單找到匯入匯出,選擇匯入sim卡連絡人,進入SimContactsSelectActivity.java這個類,在這個類裡會執行query()方法,對應的provider和uri分別是IccProvider.java與uri.parse(content://icc/adn),進入IccProvider.java後的代碼是本文要關注的部分,從query()方法看起

 

[java] view plaincopy

  1. public Cursor query(Uri url, String[] projection, String selection,  
  2.       String[] selectionArgs, String sort) {  
  3.   ArrayList<ArrayList> results;  
  4.       switch (URL_MATCHER.match(url)) {  
  5.           case ADN:  
  6.           results = loadFromEf(IccConstants.EF_ADN);  
  7.           break;  

 

       我們關心這個loadFromEf()方法,IccConstants.EF_AND這個值是6F3A,這是告訴告訴我們要先去尋找卡上這個位置的內容。  

 

[java] view plaincopy

  1. private ArrayList<ArrayList> loadFromEf(int efType) {  
  2.     ArrayList<ArrayList> results = new ArrayList<ArrayList>();  
  3.     List<AdnRecord> adnRecords = null;   
  4.     try {  
  5.         IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface(//Binder來了                    ServiceManager.getService("simphonebook"));  
  6.         if (iccIpb != null) {  
  7.             adnRecords = iccIpb.getAdnRecordsInEf(efType);//proxy模式  
  8.         }  
  9.     } …省略次要代碼….        }  

 

        接下來代碼走到IccPhoneBookInterfaceManager.java這個類的getAdnRecordsInEf(intefid)方法,其中涉及了代理模式,IccPhoneBookInterfaceManagerProxy.java在中間做了個轉換。在getAdnRecordsInEf(intefid)方法裡調用了下updateEfForIccType(efid),判斷是sim卡還是usim卡,確定下面的efid是用IccConstants.EF_AND還是IccConstants.EF_PBR,真正的查詢是requestLoadAllAdnLike()是這個方法,這裡要注意EVENT_LOAD_DONE這個標誌,要用它來接收查詢結果的。

[java] view plaincopy

  1. requestLoadAllAdnLike (int efid, int extensionEf, Message response) {  
  2.     ArrayList<Message> waiters;  
  3.     ArrayList<AdnRecord> result;  
  4.     if (efid == EF_PBR) {  //usim卡,這裡我們看這個方法  
  5.         result = mUsimPhoneBookManager.loadEfFilesFromUsim();  
  6.     } else {//sim卡  
  7.         result = getRecordsIfLoaded(efid);  
  8.     }。  

 

       看下loadEfFilesFromUsim()方法,迴圈讀取直到所有file讀完後再返回,裡面又分了兩種,一種是電話號碼的連絡人,一種是郵箱地址的連絡人,郵箱的相比電話號碼還要麻煩點。

[java] view plaincopy

  1. public ArrayList<AdnRecord> loadEfFilesFromUsim() {  
  2.      synchronized (mLock) {  
  3.         //…省略次要代碼….  
  4.          numRecs = mPbrFile.mFileIds.size();  
  5.          for (int i = 0; i < numRecs; i++) {  
  6.              readAdnFileAndWait(i);  
  7.              readEmailFileAndWait(i);  
  8.          } // All EF files are loaded, post the response.  
  9.      }  

 

       readAdnFileAndWait(i)和readEmailFileAndWait(i)最後都會調用mPhone.getIccFileHandler().loadEFLinearFixedAll()方法,只不過具體的參數不同。看下loadEFLinearFixedAll()的代碼。

[java] view plaincopy

  1. public void loadEFLinearFixedAll(int fileid, Message onLoaded) {  
  2.     Message response = obtainMessage(EVENT_GET_RECORD_SIZE_DONE,  
  3.                     new LoadLinearFixedContext(fileid,onLoaded));  
  4.     phone.mCM.iccIO(COMMAND_GET_RESPONSE, fileid, getEFPath(fileid),  
  5.                     0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, response);  
  6. }  

        iccIO()方法顯示代碼跑到RIL.java了, 之前讀卡上的資訊代碼也是走這裡       

[java] view plaincopy

  1.  public void iccIO (int command, int fileid, String path, int p1, int p2, int p3,  
  2.          String data, String pin2, Message result) {        
  3.      RILRequest rr = RILRequest.obtain(RIL_REQUEST_SIM_IO, result);//關注這個TAG標誌  
  4.      rr.mp.writeInt(command);  
  5.      rr.mp.writeInt(fileid);  
  6.      rr.mp.writeString(path);  
  7.      rr.mp.writeInt(p1);  
  8.      rr.mp.writeInt(p2);  
  9.      rr.mp.writeInt(p3);  
  10.      rr.mp.writeString(data);  
  11.      rr.mp.writeString(pin2);  
  12.      send(rr);  
  13.  }  
  14. 根據上面那個TAG,可以在Reference-ril.c找到這個分支。  
  15. case RIL_REQUEST_SIM_IO:  
  16.          requestSIM_IO(data,datalen,t);  
  17.          break;  

      閱讀requestSIM_IO()方法可以看到android源碼是如何讀取sim卡上的連絡人的,源碼使用了AT +CRSM命令,關於AT命令可以看3gpp 27.007這個文檔。讀取完成時會收到EVENT_PBR_LOAD_DONE這個訊息,在裡面createPbrFile()方法中完成字串的解析得到連絡人資訊。

 

[java] view plaincopy

  1. public void handleMessage(Message msg) {  
  2.  …省略代碼….      
  3.         switch (msg.what) {  
  4.             case EVENT_PBR_LOAD_DONE:  
  5.                 if (ar.exception == null) {  
  6.                     createPbrFile((ArrayList<byte[]>) ar.result);  
  7.                 }…省略代碼….                 
  8.                 break;  

 

        到這裡,卡連絡人匯入大部分流程就走完了,後面還有些寫入連絡人資料庫的操作比較簡單就不寫了,總體上流程還算清晰,只是迴圈比較多,遠端偵錯的時候並不是很方便,通常一個sim卡可以存250個連絡人,一個usim卡能存的連絡人要多些,但數量不固定,其中讀寫連絡人的郵箱地址要麻煩一些,由於儲存空間的限制需要多次找對應的索引能找到我們想要的東西。至於讀寫卡連絡人的具體例子,後續單獨補充吧。最後貼圖一張,有圖有真相。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.