微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在iOS 5.1中获取CellID,MCC,MNC,LAC和网络

我需要在iOS 5.1(iPhone 4S)中检索当前服务单元塔的CellID,MCC,MNC,LAC和网络(GSM,3G).我知道这些信息是可用的,因为我可以在FieldTest模式下看到它(在呼叫* 3001#12345#*后可访问).我想它可以通过私人/未记录的iOS框架访问.

iphone,check values of cellId / Lac的问题中,作者表示我可以在iOS上收到radioId信息cellId,Lac,但是没有提供有关如何做的信息.

有人可以告诉我如何获得这个信息?

解决方法

我知道如何在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,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*,CFArrayRef*);
#define _CTServerConnectionCellMonitorcopyCellInfo(connection,tmp,cells) { struct CTResult res; _CTServerConnectionCellMonitorcopyCellInfo(&res,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,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,CFNotificationSuspensionBehavior);

CTTelephonyCenteraddobserver(CTTelephonyCenterGetDefault(),NULL,callback,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,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,int*);

#ifdef __LP64__

void _CTServerConnectionGetLocationAreaCode(id,int*);
void _CTServerConnectionGetCellID(id,int*);

#else

void _CTServerConnectionGetLocationAreaCode(struct CTResult*,int*);
#define _CTServerConnectionGetLocationAreaCode(connection,LAC) { struct CTResult res; _CTServerConnectionGetLocationAreaCode(&res,LAC); }

void _CTServerConnectionGetCellID(struct CTResult*,int*);
#define _CTServerConnectionGetCellID(connection,CID) { struct CTResult res; _CTServerConnectionGetCellID(&res,CID); }

#endif

int CID,LAC,MNC;

id CTConnection = _CTServerConnectionCreate(NULL,NULL);
_CTServerConnectionGetCellID(CTConnection,&CID);
_CTServerConnectionGetLocationAreaCode(CTConnection,&LAC);
MCC = [[(Nsstring*)CTSimsupportcopyMobileSubscriberCountryCode(NULL) autorelease] intValue];
MNC = [[(Nsstring*)CTSimsupportcopyMobileSubscriberNetworkCode(NULL) autorelease] intValue];

UPDATE

在ARM64(iPhone 5S)上,所有CoreTelephony函数都接受struct CTResult参数的问题.显然,64位版本的CoreTelephony导出这些函数,而没有结构化的CTResult参数.因为如果你像以前一样调用这些函数,那么你将会在ARM64中收到错误 – 参数会出错.我更新了函数声明,使它们可以在32位和64位ARM架构上工作.我测试了它,它适用于iPhone 4S和iPhone 5S.

这仅适用于ARM64.如果您为32位ARM架构构建项目,那么就没有这样的问题.您的应用程序将使用32位版本的CoreTelephony,该版本需要使用struct CTResult参数.

8.3更新

从iOS 8.3起,所有上述解决方案都需要授权才能工作

<key>com.apple.CommCenter.fine-grained</key>
<array>
    <string>spi</string>
</array>

不仅单元监视器受到保护,而且似乎所有CoreTelephony通知现在都要求该权限工作.例如,kCTMessageReceivednotification也受到影响.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐