Obtenga CellID, MCC, MNC, LAC y red en iOS 5.1

Necesito recuperar CellID, MCC, MNC, LAC y Red (GSM, 3G) de la Torre de Celdas de Servicio actual en iOS 5.1 (iPhone 4S). Sé que esta información está disponible porque puedo verla en el modo FieldTest (accesible después de llamar a **** 3001 # 12345 # ****). Supongo que será accesible a través de marcos de iOS privados / no documentados.

En la pregunta iphone, compruebe los valores de cellId / Lac, el autor indica que puedo obtener Informaciones de radio cellId, Lac, MNC, MCC en iOS , pero no se proporciona información sobre cómo hacerlo.

¿Alguien puede decirme cómo obtener esta información?

Conozco tres formas de cómo hacerlo en iOS 5.x – 7.x. Todos ellos usan API privadas de CoreTelephony.framework. Admite GSM y UMTS.

1) Usar el monitor de la célula

 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) Usando CTTelephonyCenter

kCTRegistrationCellChangedNotification se envía cada vez que se cambia la torre de la celda de servicio actual.

 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) Esto devuelve la torre de la celda de servicio actual

 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]; 

ACTUALIZAR

En ARM64 (iPhone 5S) hay un problema con todas las funciones de CoreTelephony que aceptan el argumento struct CTResult . Aparentemente, la versión de 64 bits de CoreTelephony exporta estas funciones sin el argumento struct CTResult . Debido a eso, obtendrá un error en ARM64 si llama a estas funciones como lo hizo en el pasado: los argumentos serán incorrectos. Actualicé las declaraciones de funciones para que funcionen tanto en architectures ARM de 32 bits como de 64 bits. Lo probé y funciona tanto en el iPhone 4S como en el iPhone 5S.

Esto solo se aplica a ARM64. Si construye su proyecto para la architecture ARM de 32 bits, entonces no hay tal problema. Su aplicación usará la versión de 32 bits de CoreTelephony que espera el argumento struct CTResult .

8.3 ACTUALIZACIÓN

A partir de iOS 8.3, todas las soluciones anteriores requieren derecho a trabajar

 com.apple.CommCenter.fine-grained  spi  

No solo el monitor celular está protegido, sino que parece que todas las notificaciones de CoreTelephony ahora requieren ese derecho para funcionar. Por ejemplo, kCTMessageReceivedNotification también se ve afectado.

suscriberCellularProvider es un método de objeto (vs método de clase).

Puede ver cómo usarlo aquí: Determinar el país del usuario de iPhone

Creo que CTCarrier tiene MCC y MNC.

Puede verificar el tipo de red usando el código de esta pregunta: Cómo verificar si el iPhone admite CDMA o GSM

Y mira esta pregunta para CellID: CTServerConnectionGetCellID rutina core telefonía

El siguiente código es cómo insertarlo para que el código funcione en iOS 8.3. A partir de iOS 8.3, todas las soluciones anteriores requieren derecho a trabajar

 com.apple.CommCenter.fine-grained  spi  

De hecho, se menciona que el código mencionado anteriormente se puede ejecutar para obtener el lac y la celda en ios 8.3 y superiores. Pero realmente no sé cómo insertar lo anterior en un teléfono con jailbreak. ¿Alguien podría dar información detallada?

    Intereting Posts