在iOS 5.1中获取CellID,MCC,MNC,LAC和networking
我需要在iOS 5.1(iPhone 4S)中检索当前服务单元塔的CellID,MCC,MNC,LAC和networking(GSM,3G)。 我知道这个信息是可用的,因为我可以在FieldTest模式下看到它(调用**** 3001#12345#****后可以访问)。 我想它可以通过私人/未logging的iOS框架访问。
在iphone的问题,检查cellId / Lac作者指出我可以在iOS上获得无线电信息cellId,Lac,MNC,MCC的值 ,但没有提供有关如何做到这一点的信息。
有谁能告诉我如何得到这个信息?
我知道如何在iOS 5.x – 7.x上使用三种方法。 他们都使用CoreTelephony.framework的私有API。 支持GSM和UMTS。
1)使用单元监视器
struct CTResult { int flag; int a; }; extern CFStringRef const kCTCellMonitorCellType; extern CFStringRef const kCTCellMonitorCellTypeServing; extern CFStringRef const kCTCellMonitorCellTypeNeighbor; extern CFStringRef const kCTCellMonitorCellId; extern CFStringRef const kCTCellMonitorLAC; extern CFStringRef const kCTCellMonitorMCC; extern CFStringRef const kCTCellMonitorMNC; extern CFStringRef const kCTCellMonitorUpdateNotification; id _CTServerConnectionCreate(CFAllocatorRef, void*, int*); void _CTServerConnectionAddToRunLoop(id, CFRunLoopRef, CFStringRef); #ifdef __LP64__ void _CTServerConnectionRegisterForNotification(id, CFStringRef); void _CTServerConnectionCellMonitorStart(id); void _CTServerConnectionCellMonitorStop(id); void _CTServerConnectionCellMonitorCopyCellInfo(id, void*, CFArrayRef*); #else void _CTServerConnectionRegisterForNotification(struct CTResult*, id, CFStringRef); #define _CTServerConnectionRegisterForNotification(connection, notification) { struct CTResult res; _CTServerConnectionRegisterForNotification(&res, connection, notification); } void _CTServerConnectionCellMonitorStart(struct CTResult*, id); #define _CTServerConnectionCellMonitorStart(connection) { struct CTResult res; _CTServerConnectionCellMonitorStart(&res, connection); } void _CTServerConnectionCellMonitorStop(struct CTResult*, id); #define _CTServerConnectionCellMonitorStop(connection) { struct CTResult res; _CTServerConnectionCellMonitorStop(&res, connection); } void _CTServerConnectionCellMonitorCopyCellInfo(struct CTResult*, id, void*, CFArrayRef*); #define _CTServerConnectionCellMonitorCopyCellInfo(connection, tmp, cells) { struct CTResult res; _CTServerConnectionCellMonitorCopyCellInfo(&res, connection, tmp, cells); } #endif
…
id CTConnection = _CTServerConnectionCreate(NULL, CellMonitorCallback, NULL); _CTServerConnectionAddToRunLoop(CTConnection, CFRunLoopGetCurrent(), kCFRunLoopCommonModes); _CTServerConnectionRegisterForNotification(CTConnection, kCTCellMonitorUpdateNotification); _CTServerConnectionCellMonitorStart(CTConnection); int CellMonitorCallback(id connection, CFStringRef string, CFDictionaryRef dictionary, void *data) { int tmp = 0; CFArrayRef cells = NULL; _CTServerConnectionCellMonitorCopyCellInfo(connection, (void*)&tmp, &cells); if (cells == NULL) { return 0; } for (NSDictionary* cell in (NSArray*)cells) { int LAC, CID, MCC, MNC; if ([cell[(NSString*)kCTCellMonitorCellType] isEqualToString:(NSString*)kCTCellMonitorCellTypeServing]) { LAC = [cell[(NSString*)kCTCellMonitorLAC] intValue]; CID = [cell[(NSString*)kCTCellMonitorCellId] intValue]; MCC = [cell[(NSString*)kCTCellMonitorMCC] intValue]; MNC = [cell[(NSString*)kCTCellMonitorMNC] intValue]; } else if ([cell[(NSString*)kCTCellMonitorCellType] isEqualToString:(NSString*)kCTCellMonitorCellTypeNeighbor]) { } } CFRelease(cells); return 0; }
2)使用CTTelephonyCenter
每当当前服务小区塔改变时,发送kCTRegistrationCellChangedNotification
。
extern CFStringRef const kCTRegistrationCellChangedNotification; extern CFStringRef const kCTRegistrationGsmLac; extern CFStringRef const kCTRegistrationLac; extern CFStringRef const kCTRegistrationGsmCellId; extern CFStringRef const kCTRegistrationCellId; CFStringRef CTSIMSupportCopyMobileSubscriberCountryCode(CFAllocatorRef); CFStringRef CTSIMSupportCopyMobileSubscriberNetworkCode(CFAllocatorRef); id CTTelephonyCenterGetDefault(); void CTTelephonyCenterAddObserver(id, void, CFNotificationCallback, CFStringRef, void, CFNotificationSuspensionBehavior);
…
CTTelephonyCenterAddObserver(CTTelephonyCenterGetDefault(), NULL, callback, NULL, NULL, CFNotificationSuspensionBehaviorHold); void callback(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) { NSString* notification = (NSString*)name; NSDictionary *cellInfo = (NSDictionary*)userInfo; if ([notification isEqualToString:(NSString*)kCTRegistrationCellChangedNotification]) { int LAC, CID, MCC, MNC; if (cellInfo[(NSString*)kCTRegistrationGsmLac]) { LAC = [cellInfo[(NSString*)kCTRegistrationGsmLac] intValue]; } else if (data[(NSString*)kCTRegistrationLac]) { LAC = [cellInfo[(NSString*)kCTRegistrationLac] intValue]; } if (cellInfo[(NSString*)kCTRegistrationGsmCellId]) { CID = [cellInfo[(NSString*)kCTRegistrationGsmCellId] intValue]; } else if (cellInfo[(NSString*)kCTRegistrationCellId]) { CID = [cellInfo[(NSString*)kCTRegistrationCellId] intValue]; } MCC = [[(NSString*)CTSIMSupportCopyMobileSubscriberCountryCode(NULL) autorelease] intValue]; MNC = [[(NSString*)CTSIMSupportCopyMobileSubscriberNetworkCode(NULL) autorelease] intValue]; } }
3)这返回当前的服务小区塔
struct CTResult { int flag; int a; }; id _CTServerConnectionCreate(CFAllocatorRef, void*, int*); #ifdef __LP64__ void _CTServerConnectionGetLocationAreaCode(id, int*); void _CTServerConnectionGetCellID(id, int*); #else void _CTServerConnectionGetLocationAreaCode(struct CTResult*, id, int*); #define _CTServerConnectionGetLocationAreaCode(connection, LAC) { struct CTResult res; _CTServerConnectionGetLocationAreaCode(&res, connection, LAC); } void _CTServerConnectionGetCellID(struct CTResult*, id, int*); #define _CTServerConnectionGetCellID(connection, CID) { struct CTResult res; _CTServerConnectionGetCellID(&res, connection, CID); } #endif
…
int CID, LAC, MCC, MNC; id CTConnection = _CTServerConnectionCreate(NULL, NULL, NULL); _CTServerConnectionGetCellID(CTConnection, &CID); _CTServerConnectionGetLocationAreaCode(CTConnection, &LAC); MCC = [[(NSString*)CTSIMSupportCopyMobileSubscriberCountryCode(NULL) autorelease] intValue]; MNC = [[(NSString*)CTSIMSupportCopyMobileSubscriberNetworkCode(NULL) autorelease] intValue];
UPDATE
在ARM64(iPhone 5S)上,接受struct CTResult
参数的所有CoreTelephony函数struct CTResult
问题。 显然,CoreTelephony的64位版本导出这些函数没有struct CTResult
参数。 正因如此,如果您像以前一样调用这些函数,您将在ARM64上遇到错误 – 参数将会出错。 我更新了函数声明,以便它们可以在32位和64位ARM体系结构上工作。 我testing了它,它可以在iPhone 4S和iPhone 5S上使用。
这仅适用于ARM64。 如果您为32位ARM架构构build项目,那么不存在这样的问题。 您的应用程序将使用32位版本的CoreTelephony,它需要struct CTResult
参数。
8.3更新
从iOS 8.3开始,所有上述解决scheme都需要工作权限
<key>com.apple.CommCenter.fine-grained</key> <array> <string>spi</string> </array>
不仅电池监视器受到保护,而且似乎所有的CoreTelephony通知现在都需要该权限才能工作。 例如, kCTMessageReceivedNotification
也受到影响。
suscriberCellularProvider是一个对象方法(VS类方法)。
你可以看看如何在这里使用它: 确定iPhone用户的国家
我认为CTCarrier有MCC和MNC。
您可以使用这个问题的代码来检查networkingtypes: 如何检查iPhone是否支持CDMA或GSM
看看CellID: CTServerConnectionGetCellID例程核心电话的这个问题
下面的代码是如何插入到权利,以meke代码工作在ios 8.3上。 从iOS 8.3开始,所有上述解决scheme都需要工作权限
<key>com.apple.CommCenter.fine-grained</key> <array> <string>spi</string> </array>
的确,上面提到的代码据说可以在ios 8.3和更高版本上运行,以获取lac和cell。 但我真的不知道如何将上述插入越狱手机。 任何人都可以提供任何详细信息