android 联系人 --- 读取usim卡的邮箱

本文主要关于usim卡上邮箱地址分析实例的,同时也附带了一个联系人号码的例子,之前分别写过读取sim/usim卡上短信息和联系人信息的文章,偏向代码调用流程,这次把重点放在具体解析过程。本文可以结合下面的链接一起看。
  
   1 .android -- sim/usim卡导联系人    
   3.关于sim/usim的一些概念
  
       我们从这里开始 UsimPhoneBookManager.java的内部类PbrFile.java,从卡上读出来的字节数据在这里解析,代码不算多,流程也还清晰,PbrFile.java的构造函数里调用parseTag,parseTag中又调用parseEf,先看下代码再一起分析。 下面是具体的代码,
    
  1. private class PbrFile {       
  2.      HashMap<Integer,Map<Integer,Integer>> mFileIds;  
  3.   
  4.      PbrFile(ArrayList<byte[]> records) {  
  5.          mFileIds = new HashMap<Integer, Map<Integer, Integer>>();  
  6.          SimTlv recTlv;  
  7.          int recNum = 0;  
  8.          for (byte[] record: records) {  
  9.              recTlv = new SimTlv(record, 0, record.length);  
  10.              parseTag(recTlv, recNum);  
  11.              recNum ++;  
  12.          }  
  13.      }  
  14.   
  15.      void parseTag(SimTlv tlv, int recNum) {  
  16.          SimTlv tlvEf;  
  17.          int tag;  
  18.          byte[] data;  
  19.          Map<Integer, Integer> val = new HashMap<Integer, Integer>();  
  20.          do {  
  21.              tag = tlv.getTag();  
  22.              switch(tag) {  
  23.              case USIM_TYPE1_TAG: // A8  
  24.              case USIM_TYPE3_TAG: // AA  
  25.              case USIM_TYPE2_TAG: // A9  
  26.                  data = tlv.getData();  
  27.                  tlvEf = new SimTlv(data, 0, data.length);  
  28.                  parseEf(tlvEf, val, tag);  
  29.                  break;  
  30.              }  
  31.          } while (tlv.nextObject());  
  32.          mFileIds.put(recNum, val);  
  33.      }  
  34.   
  35.      void parseEf(SimTlv tlv, Map<Integer, Integer> val, int parentTag) {  
  36.          int tag;  
  37.          byte[] data;  
  38.          int tagNumberWithinParentTag = 0;  
  39.          do {  
  40.              tag = tlv.getTag();  
  41.              if (parentTag == USIM_TYPE2_TAG && tag == USIM_EFEMAIL_TAG) {  
  42.                  mEmailPresentInIap = true;  
  43.                  mEmailTagNumberInIap = tagNumberWithinParentTag;  
  44.              }  
  45.              switch(tag) {  
  46.                  case USIM_EFEMAIL_TAG:  
  47.                  case USIM_EFADN_TAG:  
  48.                  case USIM_EFEXT1_TAG:  
  49.                  case USIM_EFANR_TAG:  
  50.                  case USIM_EFPBC_TAG:  
  51.                  case USIM_EFGRP_TAG:  
  52.                  case USIM_EFAAS_TAG:  
  53.                  case USIM_EFGSD_TAG:  
  54.                  case USIM_EFUID_TAG:  
  55.                  case USIM_EFCCP1_TAG:  
  56.                  case USIM_EFIAP_TAG:  
  57.                  case USIM_EFSNE_TAG:  
  58.                      data = tlv.getData();  
  59.                      int efid = ((data[0] & 0xFF) << 8) | (data[1] & 0xFF);  
  60.                      val.put(tag, efid);  
  61.                      break;  
  62.              }  
  63.              tagNumberWithinParentTag ++;  
  64.          } while(tlv.nextObject());  
  65.      }  
      首先看到以new了一个simTlv(simTlv名称来源,3gpp 31.102中 TLV:Tag length value)对象,将传过来的字节数组数组包装了一下,继续往下看在parseTag函数中的switch语句,A8、A9和AA是什么意思呢?和我们读取数组有什么关系呢?读取,清楚这三个tag是我们解析数据的基础,规则如下,
      1:USIM卡文件系统内EF文件主要分三类:标签tag为A8的type1类型文件、tag为A9的type2类型文件以及tag为AA的type3类型文件。
      2:EFEMAIL(电子邮件)的存在方式只有type1和type2两: 当EFEMAIL以type1方式存在时,其中的记录内容和电话本主文件EFADN一对一映射,即EFADN中的第N条记录与EFEMAIL文件中第N条记录一一对应; 当EFEMAIL以type2方式存在时,EFADN与EFEMAIL中的记录通过EFIAP文件相关联。EFIAP是type1类型文件,与EFADN中的记录一一对应,EFIAP在文件系统内与type2类型文件必同时存在。
      PS:EFEMAIL在文件系统内可能不止一个,且存在方式可能有多种组合。
      再接下来在parseEf又出现几个tag,这里我们关注USIM_EFEMAIL_TAG(CA)、USIM_EFADN_TAG(C0)和USIM_EFIAP_TAG(C1),CA标识出电子邮件ID,C0标识的是电话号码ID,C1的作用可以理解一个索引,根据这个索引再去找CA。规则说得差不多了,来看些例子。以标准AT命令(3gpp 27.007)为例
     
读电子邮件:
    1.利用AT命令AT+CRSM=178,20272(EF_PBR:4F30),记录下标,4,0来读取EFPBR文件的记录,获取各个文件的文件ID以及短文件标识SFI。下面是两条USIM卡两条真实的数据记录。
A8  标识
1E  长度(16进制)
C0034F3A01C1034F3102C4034F5A0AC5034F4106C6034F5107C9034F6108
A9  标识
05  长度
CA034F7109
AA14C2034F4A03C7034F4B0BC8034F4C0CCB034F4F16FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

这段就不重复标注了,和上面的一样。
A8
28
C0034F3A04C1034F3105C4034F5A06C4034F6A07C4034F7A08C5034F4109C6034F510AC9034F610B
A9
05
CA034F710C
AA14
C2034F4A0DC7034F4B0EC8034F4C0FCB034F4F10

     从此真实记录中看出标识A9下有标识CA(电子邮件),EFEMAIL文件ID为4F71。标识A8下有标识C0(EFADN文件),EFADN文件ID为4F3A,短文件标识为04。标识C1(EFIAP文件)文件ID为4F31。
    读得过程中 若电子邮件是type1类型文件,则EFEMAIL与EFADN一对一映射,在对应下标处写即可。  如果电子邮件是type2类型文件则:
     1)利用AT命令读取此记录对应EFEMAIL文件中的记录下标:
          AT+CRSM=178,EFIAP文件ID,对应EFADN文件中的记录下标,4,0
          在返回的记录中找到order次序的字段值email_record_index。
     2)利用AT命令读取电子邮件文件中email_record_index下标的记录:
           AT+CRSM=178,EFEMAIL文件的ID,email_record_index,4,0

针对第二种给出一下例子
  1. ===>>[Send AT cmd][5] AT+CRSM=178,(4F31)20273,2,4,1,,3F007F105F3A,  
  2. <<====[Recv AT cmd][5] +CRSM: 144,0,01,  
  3. ===>>[Send AT cmd][5] AT+CRSM=178, (4F71)20337,1,4,42,,3F007F105F3A,  
  4. <<====[Recv AT cmd][5] +CRSM: 144,0,6775750074792E636F6DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF,  

      到这里故事还没有结束,在上面串里我们看到了EFADN,这家伙指示着电话号码,也许有时候我们还要在去这里找找电话号码,联系人的号码记录是这样
  1. ===>>[Send AT cmd][5] AT+CRSM=178,20282,1,4,28,,3F007F105F3A, time=Sat Jan  1 08:06:39 2000  
  2. <<====[Recv AT cmd][5] +CRSM: 144,0,804E09FFFFFFFFFFFFFFFFFFFFFF0480333333FFFFFFFFFFFFFFFFFF  

80、81编码格式,后面紧跟着升序  联系人名字4E09 :三, 号码:3333333(相信聪明的你已经知道80,81代表什么了)。

      内容差不多就这些,主要的东西应该都写出来了,导卡这部分给个人的感觉是如果想读全读卡上联系人信息(所有的号码和邮箱)要考虑的东西还是挺多的, 流程本身没有多复杂,但是过程比较绕,如果想导卡时间短一些,只导主要的信息就好了(比如忽略附加号码,只找一个邮箱地址),这样能快不少, 有些手机确实就是这么做的,不过这种导法从技术的角度是不应该的,对于这种时间与质量的取舍根据项目的具体要求来决定吧。
      最后,上面对于 type1类型的电子邮件还没有实例,如果你有欢迎分享一下,当然对文章写得不对地方也欢迎拍砖。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值