【发布时间】:2024-05-02 23:40:02
【问题描述】:
我目前正在使用以下方法检查Wi-Fi 是否可用于我的应用程序:
#import <SystemConfiguration/SystemConfiguration.h>
static inline BOOL addressReachable(const struct sockaddr_in *hostAddress);
BOOL localWiFiAvailable()
{
struct sockaddr_in localWifiAddress;
bzero(&localWifiAddress, sizeof(localWifiAddress));
localWifiAddress.sin_len = sizeof(localWifiAddress);
localWifiAddress.sin_family = AF_INET;
// IN_LINKLOCALNETNUM is defined in <netinet/in.h> as 169.254.0.0
localWifiAddress.sin_addr.s_addr = htonl(IN_LINKLOCALNETNUM);
return addressReachable(&localWifiAddress);
}
static inline BOOL addressReachable(const struct sockaddr_in *hostAddress)
{
const SCNetworkReachabilityRef target =
SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault,
(const struct sockaddr *)hostAddress);
if (target != NULL)
{
SCNetworkReachabilityFlags flags = 0;
const BOOL reachable = SCNetworkReachabilityGetFlags(target, &flags);
CFRelease(target);
return reachable && (flags & kSCNetworkFlagsReachable);
}
return NO;
}
但是,当 iPhone 仅连接到蜂窝网络而不是 Wi-Fi 网络时,这不会返回 NO。有谁知道如何解决这个问题?
编辑
所以这就是我最终使用的:
#import <arpa/inet.h> // For AF_INET, etc.
#import <ifaddrs.h> // For getifaddrs()
#import <net/if.h> // For IFF_LOOPBACK
BOOL localWiFiAvailable()
{
struct ifaddrs *addresses;
struct ifaddrs *cursor;
BOOL wiFiAvailable = NO;
if (getifaddrs(&addresses) != 0) return NO;
cursor = addresses;
while (cursor != NULL) {
if (cursor -> ifa_addr -> sa_family == AF_INET
&& !(cursor -> ifa_flags & IFF_LOOPBACK)) // Ignore the loopback address
{
// Check for WiFi adapter
if (strcmp(cursor -> ifa_name, "en0") == 0) {
wiFiAvailable = YES;
break;
}
}
cursor = cursor -> ifa_next;
}
freeifaddrs(addresses);
return wiFiAvailable;
}
感谢“unforgiven”(显然还有 Matt Brown)。
【问题讨论】:
-
不幸的是,这不起作用,至少不能确定 Wi-Fi 是否被激活。您可以打开 Wi-Fi,如果 Wi-Fi 适配器未连接到网络,此例程仍将返回 false。不过,谢谢。
标签: iphone objective-c cocoa-touch