android - 更改网络时接收 NETWORK_STATE_CHANGED_ACTION 已连接

标签 android networking broadcastreceiver wifi broadcast

问题:

我正在开发一个需要在不同 Wi-Fi 网络之间切换的 Android 应用程序。当用户决定连接到另一个网络时,我的应用程序必须等到连接完成,所以我需要知道什么时候发生。

为了实现这一点,我注册了一个只接收 NETWORK_STATE_CHANGED_ACTION 的 BroadcastReceiver。收到广播后,我会额外获取 NetworkInfo 并检查它是否已连接。

我在一台 Android 5.0 设备上对此进行了测试,它运行良好。但是,当我在另一台使用 Android 5.1 的设备上进行测试时,该应用程序并没有等到连接完成。发生这种情况是因为在我切换到另一个网络后立即收到广播,并且 NetworkInfo 对象指示网络已连接。

为什么会发生这种情况?

最小工作示例:

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 事件:

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-Fi 网络时,我都知道它的 ID。所以我知道当收到广播时连接完成,网络状态已连接,并且当前网络具有预期的 ID。像这样:

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!
        }
    }
}

问题仍然存在。为什么我的应用程序会收到指示网络已连接的广播,而实际上我正在断开连接?

最佳答案

与其检查来自Intent 的连接,不如尝试编写一个外部类来检查来自当前上下文的连接。

/*
 * 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 的可用性。

关于android - 更改网络时接收 NETWORK_STATE_CHANGED_ACTION 已连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35186426/

相关文章:

android - 什么会影响我的应用程序在商店中的可见性?

java:通过socket发送方法

networking - Raft 如何处理长时间的网络分区?

java - 在 BroadcastReceiver 类中打开 hibernate 的 Android 设备

java - 启动 Activity 的服务

android - 无法执行 dex : java. nio.BufferOverflowException。检查 Eclipse 日志以获取堆栈跟踪

java - Json 反序列化 - 预期为 BEGIN_OBJECT,但结果为 STRING

java - 无法从输入流读取字节数据

android - 从 Android 中的 BroadcastReceiver 调用 Activity 方法

android - 使用 SmsRetriever 时接收广播 Intent 时出错