`
xtfncel
  • 浏览: 74466 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

[转]关于读取手机号码

阅读更多

原文:http://labs.chinamobile.com/mblog/427_62947

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,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号没有争议了。
/**
     * Returns the unique device ID, for example,the IMEI for 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

分享到:
评论
2 楼 cooper100 2012-04-24  
手机号为什么取去来,会为空的?
1 楼 天天向上1989 2011-02-17  
  

相关推荐

    PDU格式发送短信读取短信中源手机号码、目的手机号码格式转换函数.zip

    PDU格式发送短信读取短信中源手机号码、目的手机号码格式转换函数

    PDU格式发送短信读取短信中源手机号码、目的手机号码格式转换函数

    PDU格式发送短信读取短信中源手机号码、目的手机号码格式转换函数

    C#开发的手机通讯录批量导入工具源代码

    安卓手机上大量录入联系人操作太麻烦,就做了这么一个程序可以将大量联系人生成可以直接导入手机通讯录的的vcf文件,用excel或记事本将“工作簿.csv”打开,录入姓名和电话号码后保存,(记事本编辑时姓名和电话号...

    python将excel中手机号批量转换为vcf文件

    python读取excel中手机号,然后批量转换为vcf文件,vcf文件可一键导入到手机里面。此功能使用了pandas模块读取excel,tkinter模块来制作GUI界面。

    NOKIAS40通讯录转文本

    本软件可能存在BUG,暂时未修复,该JAVA软件应用于手机NOKIA S40 系统可以读取通讯录那所有联系人的姓名以及手机号码!注意使用的时候一定要设置 允许增加和编辑数据,否则可能会发生异常,在一定情况下一部分手机的...

    vcf文件生成器 v4.6.zip

    vcf文件生成器将EXCEL文件的通讯录转换成vcf文件,可以直接在android系统的手机通讯录导入。...2、更换了EXCEL文件读取接口,读取更稳定,解决了非文件格式号码显示科学记数法的问题。 vcf文件生成器截图

    SIM读卡器万能驱动(手机sim卡读卡器驱动)免费安装版

    USB手机卡读卡器的功能是一样的,只是这个是标准的接口做的,直接接到计算机的COM口就可以,实际上大部分USB手机卡读卡器也是使用的USB转换的虚拟串口,速度是一样的。... 可将多个手机号码读取后合并在可擦写的Super

    手机行业常用知识(普及)

    关于手机的一些基础知 手机工作原理介绍的一编文章(续四) 手机所有软件工作的流程都是在CPU的作用下进行的,具体的划分包括下文所述的5个流程。这些流程都是以软件数据的形式储于手机的EEPROM和FLASHROM中. 一、...

    酷派tbl联系人转换txt

    这是酷派tbl短信读取器的姊妹版。 酷派tbl联系人读取器,导出联系人为文本格式,可被...仅读取联系人姓名和联系号码,忽略分组,无法重新导入手机! 在Windows 7 x64下测试通过。需要.net framework 2.0或以上支持。

    手机 pdf 阅读器

    [2009.1.1] Ver 3.2.26 ...申请了签名证书(在大多数NOKIA、SE手机上有效),请通过jad安装,没有数据线的请用手机访问http://www.ismyway.com/anyview.asp在线安装进行安装(请把读取用户数据/写入用户数据改为从不...

    MFC数字图像处理(BMP格式读取 保存 DFT FFT 直方图 色调均化 缩放 模糊 锐化 滤镜 形态学处理 曲线 裁剪 灰度图 彩色图 自动阈值)

    BMP格式读取 保存 DFT FFT 直方图 色调均化 缩放 模糊 锐化 滤镜 形态学处理 曲线 裁剪 灰度图 彩色图 自动阈值 等等...除此之外还有很多其他小功能... 建议使用VS2013打开!!!核心代码在Bmp.cpp中!!! 更新...

    QQAnalyzer 3.1 免费版专业抓去QQ协议包

    l 十六进制数转QQ号码、转IP地址、转时间格式 l QQ号码、IP地址、转时间格式转十六进制数 l QQ2011以及QQ2010以前版本的敏感字段解密密钥计算 QQAnalyzer是最专业的QQ协议辅助分析软件 目前支持版本有: 1、PCQQ:...

    Phone Suite 稳定版,通杀MTK芯片

    直接编辑手机通讯录再也不会有“读取预报信息失败”的烦人提示,有了它,你的山寨机将变得功能异常强大,再也不用使用的有缺憾的 2.4.13版,也不会再因为“玩转手机”只能编辑一个号码而烦恼,绝对值得推荐,也对得...

    Android开发人员不得不收集的代码

    charArr转byteArr chars2Bytes byteArr转charArr bytes2Chars 设备相关→DeviceUtils.java 获取设备MAC地址 getMacAddress 获取设备厂商,如Xiaomi getManufacturer 获取设备型号,如MI2SC getModel 编码解码相关→...

    Android 通讯录 Android contact源代码

    摘要:Java源码,Android源码,...弹出的上下文菜单、使用managedQuery获取ContactsProvider的Cursor、使用SimpleCursorAdapter建立Cursor的Adapter以便使用,数据表示形式为:姓名 - 手机号码、为当前ListView关联Adap

    Google Android SDK开发范例大全(第3版)part2

     10.9 转转轮盘——Lucky!  10.10 任务管理器  10.11 免费的云端发音字典  10.12 动起来!手机桌面上会动的动态桌布  10.13 正妹墙相簿浏览器  10.14 YouTube影片FLV文件下载器  第11章 HTML5 Mobile...

    《Google Android SDK开发范例大全(第3版)》.pdf

    10.9 转转轮盘——lucky! 756 10.10 任务管理器 758 10.11 免费的云端发音字典 760 10.12 动起来!手机桌面上会动的动态桌布 764 10.13 正妹墙相簿浏览器 769 10.14 youtube影片flv文件下载器 779...

    Google Android SDK开发范例大全(第3版) 1/5

    创意程序设计:即时动态桌面、电蚊香、转转轮盘、任务管理器、中英发音字典、手机手电筒、GPS轨迹记录器、女性贴身计时、QR Code二维条码生成器、手机OR Code扫描仪、热量骰子、掷杯筊、正妹墙相簿浏览器、You Tube...

    Google Android SDK开发范例大全(第3版) 4/5

    创意程序设计:即时动态桌面、电蚊香、转转轮盘、任务管理器、中英发音字典、手机手电筒、GPS轨迹记录器、女性贴身计时、QR Code二维条码生成器、手机OR Code扫描仪、热量骰子、掷杯筊、正妹墙相簿浏览器、You Tube...

Global site tag (gtag.js) - Google Analytics