Search code examples
iosiphone3giphone-privateapi4g

Get device signal strength


I am trying to get the signal strength in dBm for the carrier, wifi, 3g, and 4g.

I am currently using this code to get the carrier's and wifi from the status bar and I would like to know if there is another way or a better way? Also how could I get it for 3g and 4g?

UIApplication *app = [UIApplication sharedApplication];
NSArray *subviews = [[[app valueForKey:@"statusBar"] valueForKey:@"foregroundView"] subviews];
NSString *dataNetworkItemView = nil;
NSString *wifiNetworkItemView = nil;

for (id subview in subviews) {
    if([subview isKindOfClass:[NSClassFromString(@"UIStatusBarSignalStrengthItemView") class]]) {
        dataNetworkItemView = subview;
    }
    if([subview isKindOfClass:[NSClassFromString(@"UIStatusBarDataNetworkItemView") class]]) {
        wifiNetworkItemView = subview;
    }
}

int carrierSignalStrength = [[dataNetworkItemView valueForKey:@"signalStrengthRaw"] intValue];
int wifiSignalStrength = [[wifiNetworkItemView valueForKey:@"wifiStrengthRaw"] intValue];

It doesn't matter if any methods I use are private or not.


Solution

  • Use CoreTelephony and CTTelephonyCenter observers:

    #include <CoreTelephony/CoreTelephony.h>
    
    // Event handler
    static void SignalStrengthDidChange(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo)
    {
        long int raw = 0;
        long int graded = 0;
        long int bars = 0;
    
        CTIndicatorsGetSignalStrength(&raw, &graded, &bars);
    
        printf("Signal strength changed! Raw: %li, graded: %li bars: %li\n", raw, graded, bars);
        // Prints something like:
        // Signal strength changed! Raw: -96, graded: 27 bars: 3
    }
    

    Register the handler in another function:

    // Register as a listener to the kCTIndicatorsSignalStrengthNotification notification to be notified when the signal strength changed.
    CTTelephonyCenterAddObserver(CTTelephonyCenterGetDefault(), NULL, SignalStrengthDidChange, kCTIndicatorsSignalStrengthNotification, NULL, CFNotificationSuspensionBehaviorCoalesce);
    
    // Get the initial strength.
    SignalStrengthDidChange();
    
    CFRunLoopRun();
    

    Adapted from the iPhone Dev Wiki article on CTIndicators.

    These methods are no longer in any iOS SDKs greater than 8.4 (?) I believe. To access them, create a new header with to extern the functions and constants:

    #include <CoreFoundation/CoreFoundation.h>
    
    #if __cplusplus
    extern "C" {
    #endif
    
    #pragma mark - API
    
        /* This API is a mimic of CFNotificationCenter. */
    
        CFNotificationCenterRef CTTelephonyCenterGetDefault();
        void CTTelephonyCenterAddObserver(CFNotificationCenterRef center, const void *observer, CFNotificationCallback callBack, CFStringRef name, const void *object, CFNotificationSuspensionBehavior suspensionBehavior);
        void CTTelephonyCenterRemoveObserver(CFNotificationCenterRef center, const void *observer, CFStringRef name, const void *object);
        void CTTelephonyCenterRemoveEveryObserver(CFNotificationCenterRef center, const void *observer);
    
        void CTIndicatorsGetSignalStrength(long int *raw, long int *graded, long int *bars);
    
    #pragma mark - Definitions
    
        /* For use with the CoreTelephony notification system. */
        extern CFStringRef kCTIndicatorsSignalStrengthNotification;
    
    #if __cplusplus
    }
    #endif