关于android读取ICCID、IMSI和IMEI android imei imsi

2010年原创于http://labs.chinamobile.com/mblog/427_62947,竟然有人原封不动的写在自己的sina博客里。我们说一下大家在做android客户端软件存在的一个问题,msisdn一般很难拿到没法直接标识用户,只能采取注册用户的方法,如果你是互联网服务已有的用户可以直接登录,如果不是的话用户一看到注册是否就会跑掉大半。这里会引出下一个问题,就是那ICCID、MSISDN、ISMI到底从哪来是最准确的呢?实际上android也是通过读取卡片相关数据获取的,因此卡内存储的数据是最准确的,那么问题来了是否我们的应用可以自己读取卡内相关文件获取这些数据呢?这个要在开一个专题聊了,敬请期待。msisdn目前的方法是通过客户端给自己的后台发一个短信,由运营商的网络将此短信附加上MSISDN,我们也就有了用户的标识。再来看看http://developer.android.com/reference/android/telephony/TelephonyManager.html说明的是否和我当初的写法一致:
getSubscriberId()Returns the unique subscriber ID, forexample, the IMSI for a GSM phone.

getSimSerialNumber()Returns the serial number of the SIM, ifapplicable.

getLine1Number()Returns the phone number string for line1, for example, the MSISDN for a GSM phone.
getDeviceId()Returns the unique device ID, for example,the IMEI for GSM and the MEID or ESN for CDMA phones.
1.从一个错误代码引出我们的讨论:
android公开的API提供了访问方法,大家都知道使用TelephonyManager提供的方法,但是有些理解有误,如下国内一个比较大的andorid论坛提供的例子,就出现了错误:
帖子如下http://www.eoeandroid.com/thread-14027-1-3.html,其中实现代码没有注释,只能按照变量定义判断:
TelephonyManager tm = (TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE);
String deviceid = tm.getDeviceId();
String tel =tm.getLine1Number();//取出用户手机号码?
String imei =tm.getSimSerialNumber();//取出IMEI?
String imsi=tm.getSubscriberId();//取出IMSI?

那么上述出现错误了:String imei =tm.getSimSerialNumber();//取出IMEI
IMEI是手机的序列号,怎么会通过getSimSerialNumber()方法获得,那么查一下andorid源码可以看出:
http://www.netmite.com/android/mydroid/frameworks/base/telephony/java/android/telephony/TelephonyManager.java
从注释里明显看出来这个函数是取SIM卡序列号的,也就是ICCID的,他用错了。
    
public String getSimSerialNumber() {
try {
return getSubscriberInfo().getSimSerialNumber();
} catch (RemoteException ex) {
}
return null;
}
2.相关几个定义、说明:
我们说到的和手机、卡相关的号码数据包括IMSI,MSISDN,ICCID,IMEI
IMSI:international mobiles subscriber identity国际移动用户号码标识,
这个一般大家是不知道,GSM必须写在卡内相关文件中;
MSISDN:mobile subscriber ISDN用户号码,这个是我们说的139,136那个号码;
ICCID:ICC identity集成电路卡标识,这个是唯一标识一张卡片物理号码的;
IMEI:international mobile Equipment identity手机唯一标识码;
3.那好我们看看andorid实现TelephonyManager.java的源码:
getDeviceId()取IMEI号没有争议了。

public String getDeviceId(){
try {
returngetSubscriberInfo().getDeviceId();
} catch(RemoteException ex) {
关于android读取ICCID、IMSI和IMEI android imei imsi
}
returnnull;
}
getLine1Number()取MSISDN,这个需要说明两点,1为什么这个函数叫getLine1Number(),因为andorid实现的时候应该分为GSM和CDMA的,GSM手机使用这个函数,CDMA应该还会由其它实现的。
2取MSISDN具体的方法就会导致最后能否取到了,函数中调用了getSubscriberInfo().getLine1Number()去实现,我们下面找找看。

public StringgetLine1Number() {
try {
returngetSubscriberInfo().getLine1Number();
} catch(RemoteException ex) {
}
returnnull;
}
找到了private IPhoneSubInfo getSubscriberInfo() {
// get iteach time because that process crashes a lot
returnIPhoneSubInfo.Stub.asInterface(ServiceManager.getService("iphonesubinfo"));
}
一个接口,再找有一个PhoneSubInfo.java:

public String getDeviceId(){
mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE,"Requires READ_PHONE_STATE");
returnmPhone.getDeviceId();
}
前面定义了Phone mPhone,再找Phone.java:

StringgetSubscriberId();
原来是个接口,发现PhoneProxy.java有具体实现
public String getSubscriberId() {
returnmActivePhone.getSubscriberId();
}
这个mActivePhone是phone的实例,我疯了,于是发现GSMPHONE。java中有了具体实现:
public StringgetSubscriberId() {
returnmSIMRecords.imsi;
}

public StringgetIccSerialNumber() {
returnmSIMRecords.iccid;
}

public StringgetLine1Number() {
returnmSIMRecords.getMsisdnNumber();
从上面看出来,应该是通过SIM卡相关文件记录得到的上述数据,从其中看到:
public void handleMessage(Message msg) 这个函数进行了真正的处理,重点看:

case EVENT_GET_MSISDN_DONE:
isRecordLoadResponse = true;

ar =(AsyncResult)msg.obj;

if(ar.exception != null) {
Log.d(LOG_TAG,"Invalid or missing EF[MSISDN]");//应该是从sim卡的EFmsisdn文件中取出来的
break;
}

adn =(AdnRecord)ar.result;

msisdn =adn.getNumber();
msisdnTag =adn.getAlphaTag();

Log.d(LOG_TAG, "MSISDN: " + msisdn);
break;

下面的细节就不分析了,那个问题就归结到是否可以从SIM卡的EFmsisdn文件取出手机号码了,不幸的是一般运营商不会把用户号码写在这个文件的,为什么呢?
因为这个手机号码是在用户买到卡并开通时才将IMSI和MSISDN对应上的,卡内生产出来时只有IMSI,你不知道用户喜欢那个手机号码,因此一般不先对应IMSI和MSISDN,即时有对应也不写这个文件的。

4.总结一下:
TelephonyManager tm = (TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE);
String imei =tm.getDeviceId();//取出IMEI
String tel =tm.getLine1Number();//取出MSISDN,很可能为空
String imei =tm.getSimSerialNumber();//取出ICCID
String imsi=tm.getSubscriberId();//取出IMSI

  

爱华网本文地址 » http://www.aihuau.com/a/25101010/35076.html

更多阅读

关于口角炎的原因、治疗和预防方法 颈椎病预防及治疗方法

口角炎(AngelacEheilltts)俗称“烂嘴角”,表现为口角黏膜潮红、起疱、渗血、皲裂、糜烂、结痂、脱屑,张口时口角容易出血,进食受到影响。口角炎的病因:口角炎包括营养不良性口角炎、感染性口角炎、接触性口角炎和创伤性口角炎。营养不

如何设置相机的光圈、快门和感光度? 光圈快门感光度

这篇文档主要是关于光圈、快门和ISO的话题,这三个参数在拍照时非常重要的,直接影响照片的最终效果!光圈是一个用来控制光线透过镜头,进入机身内感光面的光量的装置,它通常是在镜头内。光圈大小我们是用f值来表示,数值越大光圈孔径越小,数值

转载 辨伪影视小说中关于雍正蒸人、炸人的问题 瓷器辨伪

我真的很想对那些乱评乱写雍正的人说评价历史人物也同样要个客观公正同样是要凭良心负责任的励精图治一世不容易雍正狠是狠但雍正那是对官狠几时见他对百姓狠过?看看雍正的悦心集就能知道他为人处世的准则了个人认为二月河笔下的雍正

声明:《关于android读取ICCID、IMSI和IMEI android imei imsi》为网友死神阻击手分享!如侵犯到您的合法权益请联系我们删除