首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在改变网络时接收连接的NETWORK_STATE_CHANGED_ACTION

在改变网络时接收连接的NETWORK_STATE_CHANGED_ACTION
EN

Stack Overflow用户
提问于 2016-02-03 19:54:04
回答 1查看 2.9K关注 0票数 1

问题:

我正在开发一个Android应用程序,需要在不同的Wi网络之间切换。当用户决定连接到另一个网络时,我的应用程序必须等待连接完成,所以我需要知道何时会发生这种情况。

为此,我注册了一个BroadcastReceiver,它只接收NETWORK_STATE_CHANGED_ACTION。当接收到广播时,我会得到额外的NetworkInfo,并检查它是否连接。

我在一台Android5.0设备上测试了这个系统,它成功了。然而,当我用Android5.1在另一台设备上进行测试时,这个应用程序并没有等到连接完成。发生这种情况是因为在我切换到另一个网络之后立即接收到一个广播,并且NetworkInfo对象指示网络连接。

为什么会发生这种事?

最小工作示例:

代码语言:javascript
运行
复制
public class MainActivity extends AppCompatActivity {

    private BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            NetworkInfo info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
            Log.i("Wi-Fi network state", info.getDetailedState().toString());
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
        registerReceiver(receiver, intentFilter);
    }

    @Override
    protected void onDestroy() {
        unregisterReceiver(receiver);
        super.onDestroy();
    }
}

在运行这个程序时,我手动切换到另一个网络。下面是随后在日志中打印的NETWORK_STATE_CHANGED_ACTION事件:

代码语言:javascript
运行
复制
02-03 17:25:23.786 I/Wi-Fi network state: CONNECTED       <-- Why? I'm disconnecting :(
02-03 17:25:23.794 I/Wi-Fi network state: DISCONNECTED
02-03 17:25:23.800 I/Wi-Fi network state: DISCONNECTED
02-03 17:25:23.898 I/Wi-Fi network state: DISCONNECTED
02-03 17:25:23.941 I/Wi-Fi network state: DISCONNECTED
02-03 17:25:23.944 I/Wi-Fi network state: CONNECTING
02-03 17:25:23.955 I/Wi-Fi network state: CONNECTING
02-03 17:25:26.205 I/Wi-Fi network state: AUTHENTICATING
02-03 17:25:26.210 I/Wi-Fi network state: OBTAINING_IPADDR
02-03 17:25:26.214 I/Wi-Fi network state: OBTAINING_IPADDR
02-03 17:25:26.219 I/Wi-Fi network state: CONNECTING
02-03 17:25:26.221 I/Wi-Fi network state: OBTAINING_IPADDR
02-03 17:25:28.292 I/Wi-Fi network state: CAPTIVE_PORTAL_CHECK
02-03 17:25:28.297 I/Wi-Fi network state: CAPTIVE_PORTAL_CHECK
02-03 17:25:28.304 I/Wi-Fi network state: CONNECTED
02-03 17:25:28.312 I/Wi-Fi network state: CONNECTED
02-03 17:30:32.400 I/Wi-Fi network state: CONNECTED

谢谢!

编辑1:

我可以用一个简单的技巧来解决这个问题:每次我必须切换到另一个Wi网络时,我就知道它的ID。所以我知道连接是在接收到广播时完成的,网络状态是连接的,当前网络有预期的ID。如下所示:

代码语言:javascript
运行
复制
public void onReceive(Context context, Intent intent) {
    NetworkInfo info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);

    if (info.getState() == NetworkInfo.State.CONNECTED) {
        WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);

        if (wifiManager == null) return;

        WifiInfo connection = wifiManager.getConnectionInfo();

        if (connection != null && connection.getNetworkId() == expectedId) {
            // Connection complete!
        }
    }
}

不过,问题仍然存在。为什么我的应用程序要接收一个广播指示网络连接,而实际上,我是断开了?

EN

回答 1

Stack Overflow用户

发布于 2016-02-03 19:57:32

不要检查来自Intent的连接,而是尝试编写一个从当前上下文检查连接的外部类。

代码语言:javascript
运行
复制
/*
 * True if network available else FALSE
 */
public static boolean isNetwork(Context mContext) {
    ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
    return activeNetwork != null && activeNetwork.isConnected();
}

从您的BroadcastReceiver中,尝试调用上面的方法来确定INTERNET的可用性。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35186426

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档