ios - 获取网络信号强度
2018-04-23 本文已影响563人
逆光少年
1.虽然各种直接获取信号强度的api都被封杀了。但是还有一个另类的黑魔法可以获取到。那就是遍历UIStatusBar了
//获取网络信号强度(dBm)
- (int)getSignalStrength{
if (iPhoneX) {
id statusBar = [[UIApplication sharedApplication] valueForKeyPath:@"statusBar"];
id statusBarView = [statusBar valueForKeyPath:@"statusBar"];
UIView *foregroundView = [statusBarView valueForKeyPath:@"foregroundView"];
int signalStrength = 0;
NSArray *subviews = [[foregroundView subviews][2] subviews];
for (id subview in subviews) {
if ([subview isKindOfClass:NSClassFromString(@"_UIStatusBarWifiSignalView")]) {
signalStrength = [[subview valueForKey:@"numberOfActiveBars"] intValue];
break;
}else if ([subview isKindOfClass:NSClassFromString(@"_UIStatusBarStringView")]) {
signalStrength = [[subview valueForKey:@"numberOfActiveBars"] intValue];
break;
}
}
return signalStrength;
} else {
UIApplication *app = [UIApplication sharedApplication];
NSArray *subviews = [[[app valueForKey:@"statusBar"] valueForKey:@"foregroundView"] subviews];
NSString *dataNetworkItemView = nil;
int signalStrength = 0;
for (id subview in subviews) {
if([subview isKindOfClass:[NSClassFromString(@"UIStatusBarDataNetworkItemView") class]] && [[self getNetworkType] isEqualToString:@"WIFI"] && ![[self getNetworkType] isEqualToString:@"NONE"]) {
dataNetworkItemView = subview;
signalStrength = [[dataNetworkItemView valueForKey:@"_wifiStrengthBars"] intValue];
break;
}
if ([subview isKindOfClass:[NSClassFromString(@"UIStatusBarSignalStrengthItemView") class]] && ![[self getNetworkType] isEqualToString:@"WIFI"] && ![[self getNetworkType] isEqualToString:@"NONE"]) {
dataNetworkItemView = subview;
signalStrength = [[dataNetworkItemView valueForKey:@"_signalStrengthRaw"] intValue];
break;
}
}
return signalStrength;
}
}
-(void)displayWifiViewWithNetStatus:(NSInteger)networkStatus {
switch (networkStatus) {
case 1:
self.networkView.image = [UIImage imageNamed:@"ic_WiFi-3"];
break;
case 2:
self.networkView.image = [UIImage imageNamed:@"ic_WiFi-2"];
break;
case 3:
self.networkView.image = [UIImage imageNamed:@"ic_WiFi-1"];
break;
default:
self.networkView.image = [UIImage imageNamed:@"ic_WiFi-1"];
break;
}
}
//检查当前是否连网
- (BOOL)whetherConnectedNetwork
{
//创建零地址,0.0.0.0的地址表示查询本机的网络连接状态
struct sockaddr_storage zeroAddress;//IP地址
bzero(&zeroAddress, sizeof(zeroAddress));//将地址转换为0.0.0.0
zeroAddress.ss_len = sizeof(zeroAddress);//地址长度
zeroAddress.ss_family = AF_INET;//地址类型为UDP, TCP, etc.
// Recover reachability flags
SCNetworkReachabilityRef defaultRouteReachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&zeroAddress);
SCNetworkReachabilityFlags flags;
//获得连接的标志
BOOL didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags);
CFRelease(defaultRouteReachability);
//如果不能获取连接标志,则不能连接网络,直接返回
if (!didRetrieveFlags)
{
return NO;
}
//根据获得的连接标志进行判断
BOOL isReachable = flags & kSCNetworkFlagsReachable;
BOOL needsConnection = flags & kSCNetworkFlagsConnectionRequired;
return (isReachable&&!needsConnection) ? YES : NO;
}
//获取网络类型
- (NSString *)getNetworkType {
if (![self whetherConnectedNetwork]) return @"NONE";
UIApplication *app = [UIApplication sharedApplication];
NSArray *subviews = [[[app valueForKeyPath:@"statusBar"] valueForKeyPath:@"foregroundView"] subviews];
NSString *type = @"NONE";
for (id subview in subviews) {
if ([subview isKindOfClass:NSClassFromString(@"UIStatusBarDataNetworkItemView")]) {
int networkType = [[subview valueForKeyPath:@"dataNetworkType"] intValue];
switch (networkType) {
case 0:
type = @"NONE";
break;
case 1:
type = @"2G";
break;
case 2:
type = @"3G";
break;
case 3:
type = @"4G";
break;
case 5:
type = @"WIFI";
break;
}
}
}
return type;
}
2.还有一种使用NetworkExtension/NEHotspotHelper来获取WIFI信息。但是得向苹果申请权限。感兴趣可以研究研究。