关于android读取用户号码,手机串号,SIM卡序列号


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的,他用错了。
    /** * Returns the serial number of the SIM, if applicable. * <p> * Requires Permission: * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} */    public String getSimSerialNumber() {        try {            return getSubscriberInfo().getSimSerialNumber();        } catch (RemoteException ex) {        }        return null;    }2.相关几个定义、说明:我们说到的和手机、卡相关的号码数据包括IMSI,MSISDN,ICCID,IMEIIMSI: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号没有争议了。
/**
* Returns the unique device ID, for example,theIMEIfor GSM
* phones.
*
* <p>Requires Permission:
* {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
*/
public String getDeviceId() {
try {
return getSubscriberInfo().getDeviceId();
} catch (RemoteException ex) {
}
return null;
}
getLine1Number()取MSISDN,这个需要说明两点,1为什么这个函数叫getLine1Number(),因为andorid实现的时候应该分为GSM和CDMA的,GSM手机使用这个函数,CDMA应该还会由其它实现的。
2取MSISDN具体的方法就会导致最后能否取到了,函数中调用了getSubscriberInfo().getLine1Number()去实现,我们下面找找看。
/**
* Returns the phone number string for line 1, for example, the MSISDN
* for a GSM phone.
* <p>
* Requires Permission:
* {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
*/
public String getLine1Number() {
try {
return getSubscriberInfo().getLine1Number();
} catch (RemoteException ex) {
}
return null;
}
找到了private IPhoneSubInfo getSubscriberInfo() {
// get it each time because that process crashes a lot
return IPhoneSubInfo.Stub.asInterface(ServiceManager.getService("iphonesubinfo"));
}
一个接口,再找有一个PhoneSubInfo.java:
/**
* Retrieves the unique device ID, e.g., IMEI for GSM phones and MEID for CDMA phones.
*/
public String getDeviceId() {
mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE");
return mPhone.getDeviceId();
}
前面定义了Phone mPhone,再找Phone.java:
/**
* Retrieves the unique sbuscriber ID, e.g., IMSI for GSM phones.
*/
String getSubscriberId();
原来是个接口,发现PhoneProxy.java有具体实现
public String getSubscriberId() {
return mActivePhone.getSubscriberId();
}
这个mActivePhone是phone的实例,我疯了,于是发现GSMPHONE。java中有了具体实现:
public String getSubscriberId() {
return mSIMRecords.imsi;
}

public String getIccSerialNumber() {
return mSIMRecords.iccid;
}

public String getLine1Number() {
return mSIMRecords.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

更多相关文章

  1. 室内定位导航系统设计实现指南
  2. [Android]Android(安卓)FTP server based on Apache FTPServer
  3. android开发每日汇总【2011-11-10】
  4. Android商城购物车页面实现和逻辑实现
  5. 自定义实现简单的Android颜色选择器(附带源码)
  6. 在Android上实现WLAN的一点理解
  7. Android调用WebService之服务端实现(一)
  8. Android中activity切换动画的两种实现(附种17种动画效果)
  9. 浅谈Java中Collections.sort对List排序的两种方法

随机推荐

  1. MySQL慢查询如何定位详解
  2. IDEA无法连接mysql数据库的6种解决方法大
  3. mysqldump你可能不知道的参数
  4. IDEA连接不上MySQL端口号占用的解决
  5. IDEA配置连接MYSQL数据库遇到Failed这个
  6. MySQL从库维护经验分享
  7. 关于mysql主备切换canal出现的问题解决
  8. Linux手动部署远程的mysql数据库的方法详
  9. Navicat for MySQL 11注册码\激活码汇总
  10. 详解Navicat远程连接mysql很慢