プライベートAPI(=プライベートフレームワーク/クラス/関数を使用しない)を使用せずに、デバイスの使用に関するさまざまなデータを収集する方法を示したいと思います。
取得できる情報の説明は次のとおりです。
- 携帯信号強度:RSSI(dBm)および相対電力(「スティック」)
- WiFi信号品質(0-悪い、4-良い)
- セルラーネットワークでの登録ステータス:SIMの可用性、ネットワーク検索
- データネットワークタイプ:2G、3G、WiFi
- 1%の精度でのアキュムレーター充電(標準手段は5%の精度を与える)
- 「機内モード」はオンになっていますか?
- 目覚まし時計、Airplay、VPN、自動転送、Nike +などのさまざまなサービスが含まれています
実際には、メソッドの本質:
typedef struct { BOOL itemIsEnabled[24]; char timeString[64]; int gsmSignalStrengthRaw; int gsmSignalStrengthBars; char serviceString[100]; char serviceCrossfadeString[100]; char serviceImages[2][100]; char operatorDirectory[1024]; unsigned serviceContentType; int wifiSignalStrengthRaw; int wifiSignalStrengthBars; unsigned dataNetworkType; int batteryCapacity; unsigned batteryState; char batteryDetailString[150]; int bluetoothBatteryCapacity; int thermalColor; unsigned thermalSunlightMode : 1; unsigned slowActivity : 1; unsigned syncActivity : 1; char activityDisplayId[256]; unsigned bluetoothConnected : 1; unsigned displayRawGSMSignal : 1; unsigned displayRawWifiSignal : 1; unsigned locationIconType : 1; } iOS6Data; // retrieve data char *app = (__bridge void *)([UIApplication sharedApplication]); ptrdiff_t providerOffset = 52; char *provider = *(char**)(app + providerOffset); ptrdiff_t iOS6DataOffset = 116; iOS6Data *data = (iOS6Data*)(provider + iOS6DataOffset);
アプローチの機能を示す最小限のプログラム
enum { kTimeItem = 0, kLockItem, kAirplaneItem, kSignalStrengthItem, kServiceItem, kDataNetworkItem, kBatteryItem, kBatteryPercentItem, kNotChargingItem, kBluetoothBatteryItem, kBluetoothItem, kTTYItem, kAlarmItem, kPlusItem, kPlayItem, kLocationItem, kRotationLockItem, kDoubleHeightItem, kAirPlayItem, kVPNItem, kCallForwardItem, kActivityItem, kThermalColorItem }; typedef struct { BOOL itemIsEnabled[24]; char timeString[64]; int gsmSignalStrengthRaw; int gsmSignalStrengthBars; char serviceString[100]; char serviceCrossfadeString[100]; char serviceImages[2][100]; char operatorDirectory[1024]; unsigned serviceContentType; int wifiSignalStrengthRaw; int wifiSignalStrengthBars; unsigned dataNetworkType; int batteryCapacity; unsigned batteryState; char batteryDetailString[150]; int bluetoothBatteryCapacity; int thermalColor; unsigned thermalSunlightMode : 1; unsigned slowActivity : 1; unsigned syncActivity : 1; char activityDisplayId[256]; unsigned bluetoothConnected : 1; unsigned displayRawGSMSignal : 1; unsigned displayRawWifiSignal : 1; unsigned locationIconType : 1; } iOS6Data; void proof_of_concept() { // we need to check runtime before start NSString *systemVersion = [[UIDevice currentDevice] systemVersion] ; NSScanner *scanner = [NSScanner scannerWithString:systemVersion]; int runtime; [scanner scanInt:&runtime]; if (runtime != 6) { NSLog(@" , iOS 6"); UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@" " message:@" iOS 6." delegate:nil cancelButtonTitle:@"" otherButtonTitles:nil]; [alertView show]; return; } // retrieve data char *app = (__bridge void *)([UIApplication sharedApplication]); ptrdiff_t providerOffset = 52; char *provider = *(char**)(app + providerOffset); ptrdiff_t iOS6DataOffset = 116; iOS6Data *data = (iOS6Data*)(provider + iOS6DataOffset); // usage example NSMutableString *example = [NSMutableString stringWithCapacity:1000]; [example appendFormat: @" : %d \n", data->gsmSignalStrengthRaw ]; [example appendFormat: @" : %@\n", @(data->batteryDetailString)]; switch (data->dataNetworkType) { case 2: [example appendString: @" : 2G\n"]; break; case 3: [example appendString: @" : 3G\n"]; break; case 5: [example appendString: @" : WiFi\n"]; default: break; } if (data->itemIsEnabled[kAlarmItem]) { [example appendString:@" "]; } if (data->itemIsEnabled[kCallForwardItem]) { [example appendString:@" "]; } if (data->itemIsEnabled[kAirplaneItem]) { [example appendString:@" \" \""]; } NSLog(@"%@", example); UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Info" message:example delegate:nil cancelButtonTitle:@"" otherButtonTitles: nil]; [alertView show]; }
長所:
- データは常に最新であり、アプリケーション自体がデータの更新に関与しています(UIApplication)
- ソリューションはプライベートAPIを使用しません
短所:
- ソリューションはiOSランタイム上に構築されているため、構造と定数はiOS 5、6、7で異なります
- 受信した情報は非常に表面的なものです。たとえば、セルラーネットワークの他の統計情報を取得することはできません。
データ構造の定数と説明がどこから来るのか、その仕組みに興味がある場合は、コメントを書いて、記事を補足します。