确定3G与Edge的区别

8

我知道reachability示例可以检测网络是否可通过Wifi或Cell访问,但是否有方法确定Cell连接是3G还是EDGE?

5个回答

28

iOS 7 开始,可以通过公共方法实现:

CTTelephonyNetworkInfo *telephonyInfo = [CTTelephonyNetworkInfo new];
NSLog(@"Current Radio Access Technology: %@", telephonyInfo.currentRadioAccessTechnology);
[NSNotificationCenter.defaultCenter addObserverForName:CTRadioAccessTechnologyDidChangeNotification 
                                                object:nil 
                                                 queue:nil 
                                            usingBlock:^(NSNotification *note) 
{
    NSLog(@"New Radio Access Technology: %@", telephonyInfo.currentRadioAccessTechnology);
}];

阅读我的 objc.io 文章 以获取更多信息。


有没有简单的方法将WiFi选项整合到这个解决方案中? - Michal
问题在于有时候远程访问工具已更改,通知会返回空值... - davidOhara
有没有任何方法可以在模拟器上进行测试?我尝试了网络链接调节器,但它只模拟速度,而且通知从未触发。欢迎任何帮助。 - youssman

14

对nst的代码进行了轻微简化,以消除我在XCode 4.5中收到的编译器警告:

- (NSNumber *) dataNetworkTypeFromStatusBar {

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

    for (id subview in subviews) {
        if([subview isKindOfClass:[NSClassFromString(@"UIStatusBarDataNetworkItemView") class]]) {
            dataNetworkItemView = subview;
            break;
        }
    }
    return [dataNetworkItemView valueForKey:@"dataNetworkType"];
}

到目前为止,我找到的值键包括:

  • 0 = 没有Wifi或蜂窝移动网络
  • 1 = 2G及更早的网络?(未经证实)
  • 2 = 3G?(尚未确认)
  • 3 = 4G
  • 4 = LTE
  • 5 = Wifi

当应用程序在后台运行时,我该如何获取其状态? - Patel Jigar
这是私有API吗?如果是,苹果会拒绝吗?你有什么想法? - Nikunj Jadav
该解决方案依赖于私有API,而且它也是一种脆弱的逻辑,可能在任何时候都会出现问题。 - DevGansta

10

使用私有API,您可以直接在状态栏中读取此信息。

https://github.com/nst/MobileSignal/blob/master/Classes/UIApplication+MS.m

+ (NSNumber *)dataNetworkTypeFromStatusBar {

    UIApplication *app = [UIApplication sharedApplication];

    UIStatusBar *statusBar = [app valueForKey:@"statusBar"];

    UIStatusBarForegroundView *foregroundView = [statusBar valueForKey:@"foregroundView"];

    NSArray *subviews = [foregroundView subviews];

    UIStatusBarDataNetworkItemView *dataNetworkItemView = nil;

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

    return [dataNetworkItemView valueForKey:@"dataNetworkType"];
}

1
你可能想要将其包装在一个 @try-@catch 块中,因为它看起来在未来的 iOS 版本中可能会发生变化。不过还是很棒的! - hypercrypt
1
这是否被苹果接受?用于发布到应用商店...? - Jeremy Luisetti
该解决方案依赖于私有API,而且它也是一种脆弱的逻辑,可能在任何时候都会出现问题。 - DevGansta
正如NST所述,此方法确实使用了私有API,这将不被Apple所接受。这个解决方法是在2012年编写的,在steipete提供公共API选项之前。现在这只是出于历史目的而存在,不应该再使用。 - Jalakoo
@JasonK,使用Swift有什么适当的替代方法吗? - willbattel

8

telephonyInfo.currentRadioAccessTechnology的值:

CORETELEPHONY_EXTERN NSString * const CTRadioAccessTechnologyGPRS          __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);
CORETELEPHONY_EXTERN NSString * const CTRadioAccessTechnologyEdge          __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);
CORETELEPHONY_EXTERN NSString * const CTRadioAccessTechnologyWCDMA         __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);
CORETELEPHONY_EXTERN NSString * const CTRadioAccessTechnologyHSDPA         __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);
CORETELEPHONY_EXTERN NSString * const CTRadioAccessTechnologyHSUPA         __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);
CORETELEPHONY_EXTERN NSString * const CTRadioAccessTechnologyCDMA1x        __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);
CORETELEPHONY_EXTERN NSString * const CTRadioAccessTechnologyCDMAEVDORev0  __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);
CORETELEPHONY_EXTERN NSString * const CTRadioAccessTechnologyCDMAEVDORevA  __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);
CORETELEPHONY_EXTERN NSString * const CTRadioAccessTechnologyCDMAEVDORevB  __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);
CORETELEPHONY_EXTERN NSString * const CTRadioAccessTechnologyeHRPD         __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);
CORETELEPHONY_EXTERN NSString * const CTRadioAccessTechnologyLTE __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);

我认为这些都是可能的值。

0

不,没有公开的方法可以检测与基站连接相关的网络技术。


有没有关于实现我们私有API的参考资料,用于计算连接网络的延迟和带宽等网络特性。 - iPhonedev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接