您的位置:首页 > 移动开发 > IOS开发

如何获得ios设备中的硬件信息(下)

2012-11-09 15:50 579 查看
上篇博文提到了ios 还可以通过其他方法获得更多的硬件信息,例如mac地址,电池电量,序列号,IMIE,总磁盘大小,背光等等,现贴出我已经测试通过的程序,获取IMIE,mac地址和序列号。

首先,引入libIOkit 的两个库文件,然后可以创建UIDevice 的catagroy。

具体代码如下:

#import "network.h"

#include <sys/types.h>

#include <sys/sysctl.h>

#import <mach/mach_host.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <netdb.h>

#include <ifaddrs.h>

#include <sys/socket.h>

#include <net/if.h>

#include <net/if_dl.h>

#include <ifaddrs.h>

#if SUPPORTS_IOKIT_EXTENSIONS

#pragma mark IOKit miniheaders

#define kIODeviceTreePlane "IODeviceTree"

enum {

kIORegistryIterateRecursively = 0x00000001,

kIORegistryIterateParents = 0x00000002

};

typedef mach_port_t io_object_t;

typedef io_object_t io_registry_entry_t;

typedef char io_name_t[128];

typedef UInt32 IOOptionBits;

CFTypeRef

IORegistryEntrySearchCFProperty(

io_registry_entry_t entry,

const io_name_t plane,

CFStringRef key,

CFAllocatorRef allocator,

IOOptionBits options );

kern_return_t

IOMasterPort( mach_port_t bootstrapPort,

mach_port_t * masterPort );

io_registry_entry_t

IORegistryGetRootEntry(

mach_port_t masterPort );

CFTypeRef

IORegistryEntrySearchCFProperty(

io_registry_entry_t entry,

const io_name_t plane,

CFStringRef key,

CFAllocatorRef allocator,

IOOptionBits options );

kern_return_t mach_port_deallocate

(ipc_space_t task,

mach_port_name_t name);

@implementation UIDevice (IOKit_Extensions)

#pragma mark IOKit Utils

NSArray *getValue(NSString *iosearch)

{

mach_port_t masterPort;

CFTypeID propID = (CFTypeID) NULL;

unsigned int bufSize;

kern_return_t kr = IOMasterPort(MACH_PORT_NULL, &masterPort);

if (kr != noErr) return nil;

io_registry_entry_t entry = IORegistryGetRootEntry(masterPort);

if (entry == MACH_PORT_NULL) return nil;

CFTypeRef prop = IORegistryEntrySearchCFProperty(entry, kIODeviceTreePlane, (CFStringRef) iosearch, nil, kIORegistryIterateRecursively);

if (!prop) return nil;

propID = CFGetTypeID(prop);

if (!(propID == CFDataGetTypeID()))

{

mach_port_deallocate(mach_task_self(), masterPort);

return nil;

}

CFDataRef propData = (CFDataRef) prop;

if (!propData) return nil;

bufSize = CFDataGetLength(propData);

if (!bufSize) return nil;

//NSString *p1 = [[[NSString alloc] initWithBytes:CFDataGetBytePtr(propData) length:bufSize encoding:1] autorelease];

NSString *p1 = [[[NSString alloc] initWithBytes:CFDataGetBytePtr(propData) length:bufSize encoding:NSUTF8StringEncoding] autorelease];

mach_port_deallocate(mach_task_self(), masterPort);

return [p1 componentsSeparatedByString:@"/0"];

}

- (NSString *) imei

{

NSArray *results = getValue(@"device-imei");

if (results)

{

//return [results objectAtIndex:0];

NSString *string_content = [results objectAtIndex:0];

const char *char_content = [string_content UTF8String];

return [[NSString alloc] initWithCString:(const char*)char_content encoding:NSUTF8StringEncoding];

}

//if(results)

//{

// return [(NSString *)[results objectAtIndex:0] substringToIndex:2];

// }

return @"";

}

- (NSString *) serialnumber

{

NSArray *results = getValue(@"serial-number");

if (results) return [results objectAtIndex:0];

return nil;

}

- (NSString *) backlightlevel

{

NSArray *results = getValue(@"backlight-level");

if (results) return [results objectAtIndex:0];

return nil;

}

- (NSString *) macaddress

{

int mib[6];

size_t len;

char *buf;

unsigned char *ptr;

struct if_msghdr *ifm;

struct sockaddr_dl *sdl;

mib[0] = CTL_NET;

mib[1] = AF_ROUTE;

mib[2] = 0;

mib[3] = AF_LINK;

mib[4] = NET_RT_IFLIST;

if ((mib[5] = if_nametoindex("en0")) == 0) {

printf("Error: if_nametoindex error/n");

return NULL;

}

if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) {

printf("Error: sysctl, take 1/n");

return NULL;

}

if ((buf = malloc(len)) == NULL) {

printf("Could not allocate memory. error!/n");

return NULL;

}

if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {

printf("Error: sysctl, take 2");

return NULL;

}

ifm = (struct if_msghdr *)buf;

sdl = (struct sockaddr_dl *)(ifm + 1);

ptr = (unsigned char *)LLADDR(sdl);

NSString *outstring = [NSString stringWithFormat:@"%02x%02x%02x%02x%02x%02x", *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), *(ptr+5)];

free(buf);

return [outstring uppercaseString];

}

@end

#endif

这样就可以分别得到IMEI,序列号,背光和mac 地址。但是有时我们会想得到手机的运营商,这时候我们可以从IMSI中获取到,具体获取IMSI的方法,到目前为止还没有一个官方的api,我们一般都是从越狱后,使用toolchain获得了imsi,但是这个可能没有办法获得app store 的审核,所以可操作性不强,但是还是记录下从imsi中获取手机运营商的方法如下:

MSI共有15位,其结构如下:

MCC+MNC+MSIN ,(MNC+MSIN=NMSI)
MCC:Mobile Country Code,移动国家码,MCC的资源由国际电联(ITU)统一分配和管理,唯一识别移动用户所属的国家,共3位,中国为460;
MNC:Mobile Network Code,移动网络码,共2位,中国移动TD系统使用00,中国联通GSM系统使用01,中国移动GSM系统使用02,中国电信CDMA系统使用03,一个典型的IMSI号码为460030912121001;
MSIN:Mobile Subscriber Identification Number共有10位,其结构如下:
09+M0M1M2M3+ABCD
其中的M0M1M2M3和MDN号码中的H0H1H2H3可存在对应关系,ABCD四位为自由分配。
这样就可以依据IMSI中的MCC和MNC来确定运营商了。当然知道编码规则同时还是需要知道对应编码的的国家和网络了。



实现的代码如下:

/* China - CN

* MCC MNC Brand Operator Status Bands (MHz) References and notes

* 460 00 China Mobile Operational GSM 900/GSM 1800 UMTS (TD-SCDMA) 1880/2010

* 460 01 China Unicom Operational GSM 900/GSM 1800/ UMTS 2100 CDMA network sold to China Telecom, WCDMA commercial trial started in May 2009 and in full commercial operation as of October 2009.

* 460 02 China Mobile Operational GSM 900/GSM 1800/ UMTS (TD-SCDMA) 1880/2010

* 460 03 China Telecom Operational CDMA 800/cdma evdo 2100

* 460 05 China Telecom Operational

* 460 06 China Unicom Operational GSM 900/GSM 1800/UMTS 2100

* 460 07 China Mobile Operational GSM 900/GSM 1800/UMTS (TD-SCDMA) 1880/2010

* 460 20 China Tietong Operational GSM-R

* NA NA China Telecom&China Unicom Operational

*/

+ (NSString*)getCarrier:(NSString*)imsi

{

if (imsi == nil || [imsi isEqualToString:@"SIM Not Inserted"] ) {

return @"Unknown";

}

else {

if ([[imsi substringWithRange:NSMakeRange(0, 3)] isEqualToString:@"460"]) {

NSInteger MNC = [[imsi substringWithRange:NSMakeRange(3, 2)] intValue];

switch (MNC) {

case 00:

case 02:

case 07:

return @"China Mobile";

break;

case 01:

case 06:

return @"China Unicom";

break;

case 03:

case 05:

return @"China Telecom";

break;

case 20:

return @"China Tietong";

break;

default:

break;

}

}

}

return @"Unknown";

}

最后想要获得更多的手机硬件信息,可以参考一下的地址查看

分享个人ios开发练手之作,显示ios设备信息的程序
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: