web-dev-qa-db-ja.com

iOS 5.1でCellID、MCC、MNC、LAC、ネットワークを取得する

IOS 5.1(iPhone 4S)の現在のサービングセルタワーのCellID、MCC、MNC、LACおよびネットワーク(GSM、3G)を取得する必要があります。 FieldTestモード(**** 3001#12345#****を呼び出した後にアクセス可能)で表示できるため、この情報が利用可能であることを知っています。私はそれがプライベート/ドキュメント化されていないiOSフレームワークを介してアクセスできると思います。

質問 iphone、cellId/Lacの値を確認 作成者が示しているiOSで無線情報cellId、Lac、MNC、MCCを取得できますしかし、これを行う方法についての情報は提供されていません。

この情報を取得する方法を誰かに教えてもらえますか?

17
poorDeveloper

IOS 5.xから7.xでそれを行う方法を3つ知っています。それらはすべて、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];

[〜#〜]更新[〜#〜]

ARM64(iPhone 5S)では、struct CTResult引数を受け入れるすべてのCoreTelephony関数に問題があります。どうやら、64ビットバージョンのCoreTelephonyは、struct CTResult引数なしでこれらの関数をエクスポートします。そのため、以前と同じようにこれらの関数を呼び出すと、ARM64でエラーが発生します-引数は正しくありません。 32ビットと64ビットの両方で機能するように関数宣言を更新しましたARMアーキテクチャ。テストした結果、iPhone 4SとiPhone 5Sの両方で機能します。

これはARM64にのみ適用されます。 32ビットのプロジェクトをビルドする場合ARM=アーキテクチャの場合、そのような問題はありません。アプリケーションは、struct CTResult引数が必要な32ビットバージョンのCoreTelephonyを使用します。

8.3更新

IOS 8.3の時点で、上記のすべてのソリューションが機能するには資格が必要です

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

セルモニターが保護されるだけでなく、すべてのCoreTelephony通知が機能するためには、その資格が必要になるようです。たとえば、kCTMessageReceivedNotificationも影響を受けます。

17
creker

suscriberCellularProviderはオブジェクトメソッド(vsクラスメソッド)です。

あなたはここでそれを使用する方法を見ることができます: iPhoneユーザーの国を決定してください

CTCarrierにはMCCとMNCがあると思います。

次の質問のコードを使用して、ネットワークタイプを確認できます: iPhoneがCDMAまたはGSMをサポートしているかどうかを確認する方法

そして、CellIDのためにこの質問を見てください: CTServerConnectionGetCellIDルーチンコアテレフォニー

2
Victor Ronin

以下のコードは、iOS 8.3でコードを機能させるためにエンタイトルメントを挿入する方法です。 iOS 8.3以降では、上記のすべてのソリューションが機能するためのライセンスが必要です

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

実際、上記のコードは、iOS 8.3以降でlacとセルを取得するために実行できると言われています。しかし、私は脱獄した電話に上記を挿入する方法を本当に知りません。誰でも詳細情報を教えてもらえますか?.

0
cellmap