【问题标题】:detect hotspot enabling in iOS with private api's使用私有 api 检测 iOS 中启用的热点
【发布时间】:2015-07-04 11:58:44
【问题描述】:

好的,所以我想检测用户是否在 iOS 设备中启用了热点/网络共享。我可以使用私有 api,知道它不会进入应用商店。

我正在尝试通过private api's list/ runtime headers,但有太多无法决定哪个可能有帮助。

或者我是否可以知道 UIApplicationWillChangeStatusBarFrameNotification 在私有 api 中被触发的位置(可能会调用主动调用和激活热点等)

我试过这个detect personal hotspot 并且也使用了 CaptiveNetwork,但它只返回连接的 wi-fi ssid 而不是创建的热点。

分享的任何知识都将非常有帮助

更新:@creker

使用上面的代码,编译器显示错误“ SCDynamicStoreCreate 不可用:在 iOS 上不可用。所以我进入 SCDynamicStore.h 并更改了以下内容

    SCDynamicStoreRef
SCDynamicStoreCreate            (
                    CFAllocatorRef          allocator,
                    CFStringRef         name,
                    SCDynamicStoreCallBack      callout,
                    SCDynamicStoreContext       *context
                    )               __OSX_AVAILABLE_STARTING(__MAC_10_1,__IPHONE_NA);

    SCDynamicStoreRef
SCDynamicStoreCreate            (
                    CFAllocatorRef          allocator,
                    CFStringRef         name,
                    SCDynamicStoreCallBack      callout,
                    SCDynamicStoreContext       *context
                    )               __OSX_AVAILABLE_STARTING(__MAC_10_1,__IPHONE_6_0);

现在我能够获得状态为 1022 和 1023 的字典。只是想通过更改这样的文件来确认(以前没有做过)我在归档构建(或任何其他问题)时会遇到任何问题(或任何其他问题)事实上我们知道这段代码不会进入应用商店

【问题讨论】:

    标签: ios iphone-privateapi tethering personal-hotspot


    【解决方案1】:

    没有私有 API

    您可以通过使用 C API 枚举网络接口来检测活动的个人热点。当热点处于活动状态并且有人连接到它时,将出现带有bridge 前缀的接口。在我的 iPhone 5 上是bridge100。如果热点被禁用或没有人连接到它,则该接口甚至不会出现在列表中。

    C API 甚至会返回该网络中的 IP 地址和子网掩码。

    这就是我在应用程序中用来检测活动热点的方法。

    要获得 SSID,您需要 [[UIDevice currentDevice] name] - 个人热点 SSID 始终与设备名称匹配。

    使用私有 API

    您可以使用此代码获取有关个人热点的所有信息:

    SCDynamicStoreRef sc = SCDynamicStoreCreate(NULL, CFSTR("com.apple.wirelessmodemsettings.MISManager"), NULL, NULL);
    NSDictionary* info = (__bridge_transfer NSDictionary*)SCDynamicStoreCopyValue(sc, CFSTR("com.apple.MobileInternetSharing"));
    CFRelease(sc);
    

    info 字典在热点处于活动状态且有连接时将如下所示:

    {
        Errnum = 0;
        ExternalInterfaces =     (
            "pdp_ip0"
        );
        Hosts =     {
            Current = 1;
            Max = 5;
            MoreAllowed = 1;
            Type =         {
                AirPort = 0;
                Bluetooth = 0;
                Ethernet = 0;
                "USB-Ethernet" = 1;
            };
        };
        InternalInterfaces =     (
            bridge100
        );
        Reason = 0;
        State = 1023;
        Version = 2;
    } 
    

    当热点处于活动状态但没有连接时:

    {
        Errnum = 0;
        ExternalInterfaces =     (
        );
        Hosts =     {
            Current = 0;
            Max = 5;
            MoreAllowed = 1;
            Type =         {
                AirPort = 0;
                Bluetooth = 0;
                Ethernet = 0;
                "USB-Ethernet" = 0;
            };
        };
        InternalInterfaces =     (
        );
        Reason = 0;
        State = 1023;
        Version = 2;
    }
    

    热点未激活时:

    {
        Errnum = 45;
        ExternalInterfaces =     (
        );
        Hosts =     {
            Current = 0;
            Max = 5;
            MoreAllowed = 1;
            Type =         {
                AirPort = 0;
                Bluetooth = 0;
                Ethernet = 0;
                "USB-Ethernet" = 0;
            };
        };
        InternalInterfaces =     (
        );
        Reason = 0;
        State = 1022;
        Version = 2;
    }
    

    当热点处于活动状态时,State 密钥将等于 1023,无论活动连接如何。我不知道该值是否包含位标志。 iOS 实际上是在检查值是否等于1023

    SCDynamicStore API 来自公共 SystemConfiguration 框架,但在 iOS 平台上标记为不可用。这意味着所有标题都在那里,您只需要复制没有__OSX_AVAILABLE_STARTING 宏的定义。

    您甚至可以观察对该设置的更改 - 您可以指定要观察哪个值的键。阅读 Apple 文档了解实现细节。

    更新

    所以我进入 SCDynamicStore.h 并更改了以下内容

    我不会那样做。它不应该引起任何问题,但对我来说更改 SDK 标头不是一个好的解决方案。我建议以下。不要包含框架标题。创建您自己的标题,在其中复制您需要的所有方法,并更改或删除__OSX_AVAILABLE_STARTING

    【讨论】:

    • 这与 OP 的“检测个人热点”链接有何不同?
    • @JesseRusak,我对他的问题给出了完整的回答,包括热点的 SSID。链接中的代码使用了错误的接口名称。如您所见,寻找bridge0 是错误的——在较新的设备上它被称为bridge100。我们只需要查找前缀bridge
    • 太棒了。有效。到目前为止,我也得到了 bridge100。但我仍然想知道是否可以让热点处于活动状态,而不管没有人连接到该热点吗?
    • @creker 我已经更新了这个问题,有另一个问题希望我们可以关闭它
    • 您好,我尝试使用您的代码获取热点信息。但我得到以下错误。 'SCDynamicStoreCreate' 不可用:在 iOS 上不可用。 'SCDynamicStoreCopyValue' 下面的其他错误不可用:在 iOS 上不可用。有什么方法可以解决上述问题吗?我在 xcode6.4.iOS SDK 8.4 中尝试这些代码。非常感谢。
    猜你喜欢
    • 2010-12-16
    • 2012-11-14
    • 2013-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多