ios - 在 iOS 上检测 WiFi 启用/禁用的更好方法?

标签 ios iphone xamarin wifi

经过令人难以置信的咬牙切齿之后,我终于找到了一种方法,可以成功检测 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/

相关文章:

objective-c - 如何通过单独提供 key 文件来播放m3u8加密的播放列表?

ios - 如何在 UIWebView 而不是 Safari 中打开 UITextView 网络链接?

iphone - IOS isEqualToString 不工作

ios - Xcode如何在屏幕上截取指定区域的截图

iOS App Store 更新 - 打补丁?

iphone - 在 iPhone 上设置设备音量

xamarin - Xamarin iOS 中的自定义振动

c# - Xamarin 'Resource.Layout' 不包含 'Tabbar' 错误的定义

ios - 使用 iOS 构建主机时 Xamarin 实际在做什么?

ios - 如何检测 UITableView 何时完成加载所有行?