I'm building an app, which has two parts. In the first part, the user scans for nearby host spots and gets a list of available networks. This part works fine. The second part, is the one with a problem. In this part, the user chooses a network to connect to and the screen is updated accordingly. I implemented a broadcast receiver to catch when the user connects to the selected network. When the mobile data is turned-off, the broadcast receiver catches the right case and everything works. However, if the mobile data is on, the broadcast receiver doesn't catch the case when the connection to the wifi is happening, though I can see that the phone already connected to the wifi.
Here is my code snippet for the broadcast receiver:
mConnectivityReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
new Thread(new Runnable() {
@Override
public void run() {
final ConnectivityManager connectivityManager = (ConnectivityManager) getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
final NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
if(networkInfo != null && networkInfo.isAvailable()){
Log.e("connectivityReceiver", "networkInfo type " + networkInfo.getTypeName());
switch (networkInfo.getType()){
case ConnectivityManager.TYPE_WIFI://When mobile data is on, I never reach this case
updateUI(networkInfo);
break;
case ConnectivityManager.TYPE_MOBILE:
//do nothing.
break;
}
}
}
public void updateUI(final NetworkInfo networkInfo){
if(networkInfo.isAvailable() && networkInfo.getExtraInfo()!= null){
Log.e("connectivityReceiver","networkInfo extra: " + networkInfo.getExtraInfo());
if(networkInfo.getExtraInfo() != null){
if(networkInfo.getExtraInfo().contains(selectedNetwork)) {
networks.clear();
runOnUiThread(new Runnable() {
@Override
public void run() {
mAdapter.notifyDataSetChanged();
mDiscoverNetworksBtn.setEnabled(true);
mDiscoverNetworksBtn.setVisibility(View.VISIBLE);
mProgressbar.setVisibility(View.GONE);
mWaitMessage.setVisibility(View.GONE);
}
});
unregisterReceiver(mConnectivityReceiver);
}
else if(!networkInfo.getExtraInfo().equals("<unknown ssid>")){
Log.e("connectivityReceiver", "Error occurred while trying to connect to " + selectedNetwork);
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(IoTSetupActivity.this, "Error occurred while trying to connect to " + selectedNetwork, Toast.LENGTH_LONG).show();
mProgressbar.setVisibility(View.GONE);
mWaitMessage.setVisibility(View.GONE);
mListview.setVisibility(View.VISIBLE);
}
});
}
}
}
}
}).start();
}
};
Here is the code snippet that I use to connect to selected network:
private void connectToNetwork(final Network network){
final WifiConfiguration conf = new WifiConfiguration();
conf.SSID = "\"" + network.getNetworkName() + "\"";
conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
WifiManager wifiManager = (WifiManager)getApplicationContext().getSystemService(Context.WIFI_SERVICE);
wifiManager.addNetwork(conf);
List<WifiConfiguration> list = wifiManager.getConfiguredNetworks();
for(WifiConfiguration i : list){
if(i.SSID != null && i.SSID.equals(conf.SSID)){
registerReceiver(mConnectivityReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
Log.e("connectToNetwork", "Disconnecting from " + wifiManager.getConnectionInfo().getSSID());
boolean isDisconnected = wifiManager.disconnect();
Log.v("connectToNetwork", "isDisconnected: " + isDisconnected);
boolean isEnabled = wifiManager.enableNetwork(i.networkId, true);
Log.v("connectToNetwork", "isEnabled: " + isEnabled);
Log.e("connectToNetwork", "Trying to reconnect to " + conf.SSID);
boolean isReconnected = wifiManager.reconnect();
Log.v("connectToNetwork", "isReconnected: " + isReconnected);
// Toast.makeText(IoTSetupActivity.this,"Connected to " + conf.SSID, Toast.LENGTH_LONG).show();
break;
}
}
}
Edit according to Denis answer:
public class ConnectivityNetworkCallback extends ConnectivityManager.NetworkCallback{
@Override
public void onAvailable(android.net.Network network) {
super.onAvailable(network);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
mConnectivityManager.bindProcessToNetwork(network);
else
ConnectivityManager.setProcessDefaultNetwork(network);
NetworkInfo networkInfo = mConnectivityManager.getActiveNetworkInfo();
int connectionType = networkInfo.getType();
Log.e("networkCallback", "connectionType: " + networkInfo.getTypeName());
switch(connectionType){
case ConnectivityManager.TYPE_WIFI:
String networkName = networkInfo.getExtraInfo();
Log.e("networkCallback","network type wifi, extra: " + networkName);
break;
case ConnectivityManager.TYPE_MOBILE:
Log.e("networkCallback","network type mobile, extra: " + networkInfo.getExtraInfo());
break;
}
}
Now my problem is when I have both mobile data and Wifi on, and switch between wifi networks, sometimes the first log prints that I'm connected to mobile and doesn't fires again when the devices connects to the new wifi, and sometimes it prints that I'm connected to the new wifi.