在移动开发中,获取移动设备的各类信息是很重要的。一个至关重要的问题就是“适配”;还有就是在不同的设备及系统中有不同的新特性。要做各种机型适配和新特性的开发获得当前硬件及系统的信息是至关重要的。在iOS中有一个名为UIDevice的单实例类,它提供了一些诸如设备名称(name)、设备类型(model)、系统名称(SystemName)、系统版本(SystemVersion)和电池(batteryLevel & batteryState)的信息;在iOS4.x及后续版本中开放了CoreTelephony这个基础框架,其中还有一个名为CTCarrier的类提供了一些运营商的信息(CarrierName、MCC及MNC)等信息。但是如设备的序列号(SerialNumber),对于iPhone来说的IMEI和IMSI号都没有提供公开的获取接口。著名的骇客Erica Sadun为写了一个有关UIDevice的扩展类别(UIDevice-Extension)提供了一个利用底层C语言的方式获取IMEI等SerialNumber等信息的方式,然而该类中并没有提供一个获取IMSI的方法。随着时间的推移我们终于来到了iOS5.x时代,伴随社iOS5的发布我们也迎来了iPhone 4S的发布,坑爹的苹果在iPhone 4S中做了更多的封闭工作,使得原本可以Erica Sadun写得这个类别中的很多方法都无法获取系统信息了(如CPU的型号和频率,还有就是IMEI和SerialNumber)。
我为了找出如何获得这些设备的信息做了很多尝试,功夫不负有心人终于让我找出了获取IMEI和IMSI的新方法,下面我就来说一下如何获得这两个重要的号码:
从SpringBoard的dump出的文件中我们可以找到一个名为SBTelephonyManager.h的头文件,该文件定义了一个同名的单实例类,这个类中有一名为copyMobileEquipmentInfo的实例方法,其返回值是一个NSDictionary类型其中就包含了IMEI和ICCID这两个了号码,她们对应的键值分别为:kCTMobileEquipmentInfoIMEI和kCTMobileEquipmentInfoICCID。对于iOS5.x这个dictionary中还包含了IMSI其键值为kCTMobileEquipmentInfoIMSI,但是在iOS3和iOS4中却没有这个字段,那么在这两个版本的系统中如何获得IMSI这个号码呢?这样我们只能使用未公开的一个在CoreTelephony框架中但是没有公开的一个C函数了——CTSIMSupportCopyMobileSubscriberIdentity(),它的返回值就是我们想要的IMSI好了。