原文地址:http://stackoverflow.com/questions/13399659/get-cellid-mcc-mnc-lac-and-network-in-ios-5-1
在iOS5 ~ iOS8.3可是使用此方法,此处使用CoreTelephony.framework私有API。同时支持GSM和UMTS
1、使用电池监控器
1 struct CTResult 2 { 3 int flag; 4 int a; 5 }; 6 7 extern CFStringRef const kCTCellMonitorCellType; 8 extern CFStringRef const kCTCellMonitorCellTypeServing; 9 extern CFStringRef const kCTCellMonitorCellTypeNeighbor; 10 extern CFStringRef const kCTCellMonitorCellId; 11 extern CFStringRef const kCTCellMonitorLAC; 12 extern CFStringRef const kCTCellMonitorMCC; 13 extern CFStringRef const kCTCellMonitorMNC; 14 extern CFStringRef const kCTCellMonitorUpdateNotification; 15 16 id _CTServerConnectionCreate(CFAllocatorRef, void*, int*); 17 void _CTServerConnectionAddToRunLoop(id, CFRunLoopRef, CFStringRef); 18 19 #ifdef __LP64__ 20 21 void _CTServerConnectionRegisterForNotification(id, CFStringRef); 22 void _CTServerConnectionCellMonitorStart(id); 23 void _CTServerConnectionCellMonitorStop(id); 24 void _CTServerConnectionCellMonitorCopyCellInfo(id, void*, CFArrayRef*); 25 26 #else 27 28 void _CTServerConnectionRegisterForNotification(struct CTResult*, id, CFStringRef); 29 #define _CTServerConnectionRegisterForNotification(connection, notification) { struct CTResult res; _CTServerConnectionRegisterForNotification(&res, connection, notification); } 30 31 void _CTServerConnectionCellMonitorStart(struct CTResult*, id); 32 #define _CTServerConnectionCellMonitorStart(connection) { struct CTResult res; _CTServerConnectionCellMonitorStart(&res, connection); } 33 34 void _CTServerConnectionCellMonitorStop(struct CTResult*, id); 35 #define _CTServerConnectionCellMonitorStop(connection) { struct CTResult res; _CTServerConnectionCellMonitorStop(&res, connection); } 36 37 void _CTServerConnectionCellMonitorCopyCellInfo(struct CTResult*, id, void*, CFArrayRef*); 38 #define _CTServerConnectionCellMonitorCopyCellInfo(connection, tmp, cells) { struct CTResult res; _CTServerConnectionCellMonitorCopyCellInfo(&res, connection, tmp, cells); } 39 40 #endif
1 id CTConnection = _CTServerConnectionCreate(NULL, CellMonitorCallback, NULL); 2 _CTServerConnectionAddToRunLoop(CTConnection, CFRunLoopGetCurrent(), kCFRunLoopCommonModes); 3 _CTServerConnectionRegisterForNotification(CTConnection, kCTCellMonitorUpdateNotification); 4 _CTServerConnectionCellMonitorStart(CTConnection); 5 6 int CellMonitorCallback(id connection, CFStringRef string, CFDictionaryRef dictionary, void *data) 7 { 8 int tmp = 0; 9 CFArrayRef cells = NULL; 10 _CTServerConnectionCellMonitorCopyCellInfo(connection, (void*)&tmp, &cells); 11 if (cells == NULL) 12 { 13 return 0; 14 } 15 16 for (NSDictionary* cell in (NSArray*)cells) 17 { 18 int LAC, CID, MCC, MNC; 19 20 if ([cell[(NSString*)kCTCellMonitorCellType] isEqualToString:(NSString*)kCTCellMonitorCellTypeServing]) 21 { 22 LAC = [cell[(NSString*)kCTCellMonitorLAC] intValue]; 23 CID = [cell[(NSString*)kCTCellMonitorCellId] intValue]; 24 MCC = [cell[(NSString*)kCTCellMonitorMCC] intValue]; 25 MNC = [cell[(NSString*)kCTCellMonitorMNC] intValue]; 26 } 27 else if ([cell[(NSString*)kCTCellMonitorCellType] isEqualToString:(NSString*)kCTCellMonitorCellTypeNeighbor]) 28 { 29 } 30 } 31 32 CFRelease(cells); 33 34 return 0; 35 }
2、使用CTTelephonyCenter
kCTRegistrationCellChangedNotification
每一个服务小区塔改变时被调用。
1 extern CFStringRef const kCTRegistrationCellChangedNotification; 2 extern CFStringRef const kCTRegistrationGsmLac; 3 extern CFStringRef const kCTRegistrationLac; 4 extern CFStringRef const kCTRegistrationGsmCellId; 5 extern CFStringRef const kCTRegistrationCellId; 6 7 CFStringRef CTSIMSupportCopyMobileSubscriberCountryCode(CFAllocatorRef); 8 CFStringRef CTSIMSupportCopyMobileSubscriberNetworkCode(CFAllocatorRef); 9 10 id CTTelephonyCenterGetDefault(); 11 void CTTelephonyCenterAddObserver(id, void, CFNotificationCallback, CFStringRef, void, CFNotificationSuspensionBehavior);
1 CTTelephonyCenterAddObserver(CTTelephonyCenterGetDefault(), NULL, callback, NULL, NULL, CFNotificationSuspensionBehaviorHold); 2 3 void callback(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) 4 { 5 NSString* notification = (NSString*)name; 6 NSDictionary *cellInfo = (NSDictionary*)userInfo; 7 8 if ([notification isEqualToString:(NSString*)kCTRegistrationCellChangedNotification]) 9 { 10 int LAC, CID, MCC, MNC; 11 12 if (cellInfo[(NSString*)kCTRegistrationGsmLac]) 13 { 14 LAC = [cellInfo[(NSString*)kCTRegistrationGsmLac] intValue]; 15 } 16 else if (data[(NSString*)kCTRegistrationLac]) 17 { 18 LAC = [cellInfo[(NSString*)kCTRegistrationLac] intValue]; 19 } 20 21 if (cellInfo[(NSString*)kCTRegistrationGsmCellId]) 22 { 23 CID = [cellInfo[(NSString*)kCTRegistrationGsmCellId] intValue]; 24 } 25 else if (cellInfo[(NSString*)kCTRegistrationCellId]) 26 { 27 CID = [cellInfo[(NSString*)kCTRegistrationCellId] intValue]; 28 } 29 30 MCC = [[(NSString*)CTSIMSupportCopyMobileSubscriberCountryCode(NULL) autorelease] intValue]; 31 MNC = [[(NSString*)CTSIMSupportCopyMobileSubscriberNetworkCode(NULL) autorelease] intValue]; 32 } 33 }
3、返回当前服务小区塔
1 struct CTResult 2 { 3 int flag; 4 int a; 5 }; 6 7 id _CTServerConnectionCreate(CFAllocatorRef, void*, int*); 8 9 #ifdef __LP64__ 10 11 void _CTServerConnectionGetLocationAreaCode(id, int*); 12 void _CTServerConnectionGetCellID(id, int*); 13 14 #else 15 16 void _CTServerConnectionGetLocationAreaCode(struct CTResult*, id, int*); 17 #define _CTServerConnectionGetLocationAreaCode(connection, LAC) { struct CTResult res; _CTServerConnectionGetLocationAreaCode(&res, connection, LAC); } 18 19 void _CTServerConnectionGetCellID(struct CTResult*, id, int*); 20 #define _CTServerConnectionGetCellID(connection, CID) { struct CTResult res; _CTServerConnectionGetCellID(&res, connection, CID); } 21 22 #endif
1 int CID, LAC, MCC, MNC; 2 3 id CTConnection = _CTServerConnectionCreate(NULL, NULL, NULL); 4 _CTServerConnectionGetCellID(CTConnection, &CID); 5 _CTServerConnectionGetLocationAreaCode(CTConnection, &LAC); 6 MCC = [[(NSString*)CTSIMSupportCopyMobileSubscriberCountryCode(NULL) autorelease] intValue]; 7 MNC = [[(NSString*)CTSIMSupportCopyMobileSubscriberNetworkCode(NULL) autorelease] intValue];
更新数据
在ARM64(iPhone 5S)有与接受所有CoreTelephony功能的问题struct CTResult
争论。显然,CoreTelephony的64位版本的出口这些功能没有struct CTResult
说法。参数将是错误的-正因为如此,如果你调用这些函数像你过去那样你会得到ARM64一个错误。我更新函数声明,使他们在32位和64位ARM架构工作。我测试了它和它的作品在两个iPhone 4S的和iPhone 5S。
这仅适用于ARM64。如果你建立你的项目为32位ARM架构则没有这样的问题。您的应用程序将使用CoreTelephony的32位版本,预计struct CTResult
说法。
8.3更新
着iOS 8.3版本以上所有解决方案都需要有权工作
com.apple.CommCenter.fine-grained
spi
不仅电池监控器是受保护的,但它似乎像所有CoreTelephony通知现在要求权利的工作。例如,kCTMessageReceivedNotification
也受到影响。