看到很多人在问android中sim卡相关操作,我在一年之前在2.1上做过相应的工作吧,暂时分享下一下主要的问题吧1,sim卡联系人的增,删,修改
Uri是content://icc/adn/
具体使用跟操作其他的contentprovider一样,传递的参数可以参照\base\telephony\java\com\android\internal\telephony\IccProvider.java2,存入联系人到USIM卡的问题
这个问题的实质是普通sim卡文件的EF ID跟USIM卡中的EF ID不同造成,SIM卡中的使用的是是EF_ADN = 0x6F3A,而USIM卡中存储联系人的EFID 则为EF_PBR = 0x4F30修改办法:
1,在\base\telephony\java\com\android\internal\telephony\IccPhoneBookInterfaceManager.java 中的updateAdnRecordsInEfBySearch函数当中检查是不是使用USIM卡
加入下面一行
        if (phone.getContext().checkCallingOrSelfPermission(
                android.Manifest.permission.WRITE_CONTACTS)
            != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException(
                    "Requires android.permission.WRITE_CONTACTS permission");
        }
        // modified by leon at 5/11/2010 change sim card ef to USIM card ef if user use USIM card
        efid = updateEfForIccType(efid);
        // modified end;
        
        if (DBG) logd("updateAdnRecordsInEfBySearch: efid=" + efid +
                " ("+ oldTag + "," + oldPhoneNumber + ")"+ "==>" +
                " ("+ newTag + "," + newPhoneNumber + ")"+ " pin2=" + pin2);updateEfForIccType(efid)的实现为:
   private int updateEfForIccType(int efid) {
        // Check if we are trying to read ADN records
        if (efid == IccConstants.EF_ADN) {
            if (phone.getIccCard().isApplicationOnIcc(IccCardApplication.AppType.APPTYPE_USIM)) {
                return IccConstants.EF_PBR;
            }
        }
        return efid;
    }
在\base\telephony\java\com\android\internal\telephony\AdnRecordCache.java中我修改之后的updateAdnBySearch函数为public void updateAdnBySearch(int efid, AdnRecord oldAdn, AdnRecord newAdn,
            String pin2, Message response) {        int extensionEF;
        extensionEF = extensionEfForEf(efid);        if (extensionEF < 0) {
            sendErrorResponse(response, "EF is not known ADN-like EF:" + efid);
            return;
        }        // modified by leon  5/11/2010
        // if user use USIM card,the change the phonebook ef
        ArrayList<AdnRecord>  oldAdnList = null;
        if(efid == EF_PBR){
         int usimEf[] = mUsimPhoneBookManager.getUsimEf();
         int usimExtensionEF[] = mUsimPhoneBookManager.getUsimExtensionEF();
         int size = usimEf.length;
        
         for(int i =0;i<size;i++){
         oldAdnList = getRecordsIfLoaded(usimEf[i]);
         efid = usimEf[i];
         extensionEF = usimExtensionEF[i];
         boolean bBreak = false;
         if (oldAdnList != null){
                 for (Iterator<AdnRecord> it = oldAdnList.iterator(); it.hasNext();) {
                     if (oldAdn.isEqual(it.next())) {
                      bBreak = true;
                         break;
                     }
                 }
         }
         if(bBreak)
         break;
         }
        }else{
         oldAdnList = getRecordsIfLoaded(efid);
        }
        // modified end

                if (oldAdnList == null) {
            sendErrorResponse(response, "Adn list not exist for EF:" + efid);
            return;
        }        int index = -1;
        int count = 1;
        for (Iterator<AdnRecord> it = oldAdnList.iterator(); it.hasNext(); ) {
            if (oldAdn.isEqual(it.next())) {
                index = count;
                break;
            }
            count++;
        }        if (index == -1) {
            sendErrorResponse(response, "Adn record don't exist for " + oldAdn);
            return;
        }        Message pendingResponse = userWriteResponse.get(efid);        if (pendingResponse != null) {
            sendErrorResponse(response, "Have pending update for EF:" + efid);
            return;
        }        userWriteResponse.put(efid, response);        new AdnRecordLoader(phone).updateEF(newAdn, efid, extensionEF,
                index, pin2,
                obtainMessage(EVENT_UPDATE_ADN_DONE, efid, index, newAdn));
    }其中getUsimEf跟getUsimExtensionEF两个函数的实现如下:
  // add by leon at 5/11/2010 
    
    /****
     * @hide
     * @return usim card ef 
     */
    public int[] getUsimEf(){
     if (mPbrFile == null) return null;
     int numRecs = mPbrFile.mFileIds.size();
     int[] result = new int[numRecs];
        for (int i = 0; i < numRecs; i++) {
         Map <Integer,Integer> fileIds;
         fileIds = mPbrFile.mFileIds.get(i);
         if (fileIds == null || fileIds.isEmpty()){
         result[i] = 0;
         }else{
         result[i] = fileIds.get(USIM_EFADN_TAG);
         }
        
        }
        return result;
    }
    
    
    /****
     * @hide
     * @return usim card's extensionEF 
     */
    public int[] getUsimExtensionEF(){
     if (mPbrFile == null) return null;
     int numRecs = mPbrFile.mFileIds.size();
     int[] result = new int[numRecs];
        for (int i = 0; i < numRecs; i++) {
         Map <Integer,Integer> fileIds;
         fileIds = mPbrFile.mFileIds.get(i);
         if (fileIds == null || fileIds.isEmpty()){
         result[i] = 0;
         }else{
         result[i] = fileIds.get(USIM_EFEXT1_TAG);
         }
        
        }
        return result;
    }
    
    /****
     * @hide
     * @param adn
     * add a new adn,when export a contact to usim card
     */
    public void addUsimAdn(AdnRecord adn){
     mPhoneBookRecords.add(adn);
    }
    
    // add end这里还有一个addUsimAdn函数调用是在这个文件中handleMessage函数中,具体干啥好像是在写入USIM卡的同时也在保留一份在cache文件中
  handleMessage(Message msg) {
        AsyncResult ar;
        int efid;        switch(msg.what) 
            case EVENT_UPDATE_ADN_DONE:
                ar = (AsyncResult)msg.obj;
                efid = msg.arg1;
                int index = msg.arg2;
                AdnRecord adn = (AdnRecord) (ar.userObj);                if (ar.exception == null) {
                    adnLikeFiles.get(efid).set(index - 1, adn);
                    // add by leon  to update UsimPhoneBookManager,when export a contacts to usim card.
                    if(efid!=IccConstants.EF_ADN){
                     mUsimPhoneBookManager.addUsimAdn(adn);
                    }
                    // add end
                }
这些修改应该能把联系人存入USIM卡中了

解决方案 »

  1.   

    不错 我也做过sim联系人相关,写的不错
      

  2.   

    跟厂商的RIL有关系么?
    我记得是在framework里有判断如果名字不是ascill编码的就把名字改成空格号
    在这里修改成80编码或者81,82编码就行了
      

  3.   

    为什么我删除或修改之后再查看 联系人反而 多了 之后实际卡里联系人个数是正常的
     adnLikeFiles.get(efid).set(index - 1, adn);
      // add by leon to update UsimPhoneBookManager,when export a contacts to usim card.
      if(efid!=IccConstants.EF_ADN){
      mUsimPhoneBookManager.addUsimAdn(adn);
      }
      // add end
      }
    是这句造成的吗  ?
      

  4.   

       
    UsimPhoneBookManager.java文件中
    public ArrayList<AdnRecord> loadEfFilesFromUsim() {
          //加上下边这句,load之前清空记录,速度虽然会慢一些
    this.reset();
            synchronized (mLock) {
                if (!mPhoneBookRecords.isEmpty()) return mPhoneBookRecords;
                if (!mIsPbrPresent) return null;            // Check if the PBR file is present in the cache, if not read it
                // from the USIM.
      

  5.   

    估计多数人还是对研究sim的运营商情报感兴趣。
    联系人,存哪里不是存。反正android可绑定账户更新
      

  6.   

    支持一下 写的很好很有帮助
    有一个问题 写回时会在AdnRecord类判断字符 中文字符都会被换成空格
    如果想支持中文的话 需要在那里修改编码 如上面同学所说改成80编码