【问题标题】:Is it safe to use WifiManager.NETWORK_STATE_CHANGED_ACTION to receive broadcast when Wifi connection is established successfully?成功建立Wifi连接后使用WifiManager.NETWORK_STATE_CHANGED_ACTION接收广播是否安全?
【发布时间】:2014-08-04 01:13:14
【问题描述】:

我知道大多数人会在连接更改时检查ConnectivityManager.CONNECTIVITY_ACTION 以接收广播。但是,在某些情况下,您可能只想在无线连接成功建立时收到通知。

就个人而言,我的情况是,当用户连接到某个无线网络时,我需要发布登录请求。经过一番谷歌搜索,我找到了WifiManager.NETWORK_STATE_CHANGED_ACTION,但它的证明很差,因此它的可靠性受到怀疑。因此,我需要确认无线配置成功完成后是否会始终触发此 Intent。

无论如何,这是我在BroadcastReceiver 中使用的代码:

public class StateChangedReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {

        NetworkInfo networkInfo = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
        if (!networkInfo.isConnected()) {
            return;
        }

        WifiInfo wifiInfo = intent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO);
        if (!wifiInfo.getSSID().equals(THE_SSID_YOU_ARE_LOOKING_FOR)) {
            return;
        }

        // Do something
    }
}

【问题讨论】:

    标签: android broadcastreceiver android-wifi


    【解决方案1】:

    编辑:

    使用我的三星 S4 (I959) 设备进行测试时,我的广播接收器无法接收到广播。使用 ConnectivityManager.CONNECTIVITY_ACTION 的常用方法似乎在不同制造商之间更可靠。所以你可能想改用它。

    以下是我之前对该广播的调查。


    这是我从 4.4.4_r1 源代码中得到的。

    来自WifiStateMachinesource,首先看到的是状态机的状态,也就是inside its constructor。注意后者是前者的父状态。

    addState(mDefaultState);
        addState(mInitialState, mDefaultState);
        addState(mSupplicantStartingState, mDefaultState);
        addState(mSupplicantStartedState, mDefaultState);
            addState(mDriverStartingState, mSupplicantStartedState);
            addState(mDriverStartedState, mSupplicantStartedState);
                addState(mScanModeState, mDriverStartedState);
                addState(mConnectModeState, mDriverStartedState);
                    addState(mL2ConnectedState, mConnectModeState);
                        addState(mObtainingIpState, mL2ConnectedState);
                        addState(mVerifyingLinkState, mL2ConnectedState);
                        addState(mCaptivePortalCheckState, mL2ConnectedState);
                        addState(mConnectedState, mL2ConnectedState);
                    addState(mDisconnectingState, mConnectModeState);
                    addState(mDisconnectedState, mConnectModeState);
                    addState(mWpsRunningState, mConnectModeState);
            addState(mWaitForP2pDisableState, mSupplicantStartedState);
            addState(mDriverStoppingState, mSupplicantStartedState);
            addState(mDriverStoppedState, mSupplicantStartedState);
        addState(mSupplicantStoppingState, mDefaultState);
        addState(mSoftApStartingState, mDefaultState);
        addState(mSoftApStartedState, mDefaultState);
            addState(mTetheringState, mSoftApStartedState);
            addState(mTetheredState, mSoftApStartedState);
            addState(mUntetheringState, mSoftApStartedState);
    

    谢天谢地,这些名称几乎是不言自明的。您可以很容易地注意到我们感兴趣的状态。要了解实际发生的情况,我们可以搜索这些状态的来源。

    我们调查的第一个方法是sendNetworkStateChangeBroadcast。它的调用可以在VerifyingLinkStateCaptivePortalCheckState 中识别,其他一些您可能会自己发现。

    CaptivePortalCheckState内部,当processing CMD_CAPTIVE_CHECK_COMPLETE,你终于可以确认当检查完成并且网络完全配置时,我们将在我们的应用程序中收到状态更改意图,CONNECTED state in NetworkInfo extra随之带有WifiInfo

    最后但同样重要的是,我们回顾了历史。个人对 4.x 平台比较感兴趣,所以转向了 4.0.1_r1 的源码。这个版本似乎比后一个版本更具可读性,这有点令人惊讶。可以发现sendNetworkStateChangeBroadcasthandleSuccessfulIpConfiguration(和其他方法)内部被触发,当ip配置成功时,ConnectingState.processMessage()ConnectedState.processMessage()被触发。

    所以我们终于得出结论,使用WifiManager.NETWORK_STATE_CHANGED_ACTION跟踪成功的无线连接,是安全合适的。

    如果你还有其他关于WifiManager广播的问题,也可以参考上面提到的源码自己去寻找:)

    【讨论】:

    • 终于,一个可行的。太感谢了。你的用例正是我的。愿众神在你的道路上微笑!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-13
    相关资源
    最近更新 更多