在令人难以置信的牙齿咬牙切齿之后,我终于有了一种方法可以成功检测iOS上是否启用了WiFi,无论它是否已连接。这种事情至少有几种用途,我不认为这违反了Apple Law(tm)的精神或文字。
然而,它很丑陋,可能永远不会工作。它目前适用于iOS 10.2.1,截至2017年1月31日。我将在下面给出我的答案,并希望有人可以改进它。我对Reachability(不符合要求),CaptiveNetwork,HotspotHelper,SCNetworkConfiguration,Xamarin的System.Net.NetworkInterface等进行了大量研究。这实际上就是我能说的。
答案 0 :(得分:1)
解决方案的要点是当getifaddrs()报告的两个接口名称为" awdl0"然后启用WiFi。只有一个,它被禁用了。
我认为pebble8888指的是https://github.com/alirp88/SMTWiFiStatus,这是Objective-C,缺乏评论使得很难理解发生了什么或者作者的意图是什么。< / p>
这是我完整而完整的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