问题:
我正在开发一款需要在不同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!
}
}
}
但问题仍然存在。为什么我的应用程序会收到指示网络已连接的广播,而实际上我正在断开连接?
答案 0 :(得分:2)
尝试编写一个从当前上下文检查连接的外部类,而不是检查Action.async
的连接。
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
的可用性。