经过令人难以置信的咬牙切齿之后,我终于找到了一种方法,可以成功检测 iOS 上的 WiFi 是否启用,无论它是否连接。这样的东西至少有几种用途,我不认为这违反了 Apple Law(tm) 的精神或文字。
但是,它很丑陋,而且可能不会永远有效。截至2017年1月31日,它目前适用于iOS 10.2.1。我将我的答案放在下面,希望有人可以改进它。我深入研究了 Reachability(不满足要求)、CaptiveNetwork、HotspotHelper、SCNetworkConfiguration、Xamarin 的 System.Net.NetworkInterface 等。据我所知,这确实有效。
最佳答案
解决方案的要点是,当 getifaddrs() 报告有两个名为“awdl0”的接口(interface)时,就会启用 WiFi。只有一个,它已被禁用。
我相信 pebble8888 给我指出了 https://github.com/alirp88/SMTWiFiStatus这是 Objective-C,缺乏注释让人很难理解正在发生的事情或作者的意图。
这是我完整且完整的 Xamarin/C# 解决方案,对于任何其他主要语言用户来说应该具有良好的可读性:
using System;
using System.Runtime.InteropServices;
namespace Beacon.iOS
{
/// <summary>
/// code stolen from the Xamarin source code to work around goofy interactions between
/// the good-god-why-would-it-work-that-way iOS and the entirely reasonable Xamarin
/// (it doesn't report interfaces that are reported multiple times)
/// </summary>
class XamHack
{
//
// Types
//
internal struct ifaddrs
{
#pragma warning disable 0649
public IntPtr ifa_next;
public string ifa_name;
public uint ifa_flags;
public IntPtr ifa_addr;
public IntPtr ifa_netmask;
public IntPtr ifa_dstaddr;
public IntPtr ifa_data;
#pragma warning restore
}
//
// OS methods
//
[DllImport("libc")]
protected static extern int getifaddrs(out IntPtr ifap);
[DllImport("libc")]
protected static extern void freeifaddrs(IntPtr ifap);
//
// Methods
//
/// <summary>
/// Our glorious hack. I apologize to the programming gods for my sins
/// but this works (for now) and functionality trumps elegance. Even this.
/// Reverse engineered from: https://github.com/alirp88/SMTWiFiStatus
/// </summary>
public static bool IsWifiEnabled()
{
int count = 0;
IntPtr ifap;
// get the OS to put info about all the NICs into a linked list of buffers
if (getifaddrs(out ifap) != 0)
throw new SystemException("getifaddrs() failed");
try
{
// iterate throug those buffers
IntPtr next = ifap;
while (next != IntPtr.Zero)
{
// marshall the data into our struct
ifaddrs addr = (ifaddrs)Marshal.PtrToStructure(next, typeof(ifaddrs));
// count the instances of the sacred interface name
if ("awdl0" == addr.ifa_name)
count++;
// move on to the next interface
next = addr.ifa_next;
}
}
finally
{
// leaking memory is for jerks
freeifaddrs(ifap);
}
// if there's two of the sacred interface, that means WiFi is enabled. Seriously.
return (2 == count);
}
} // class
} // namespace
关于ios - 在 iOS 上检测 WiFi 启用/禁用的更好方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41969989/