In a recent project I had to be able to monitor the state of the WiFi connection. I needed to be able to notify the user about what state the connection was in in real time.

There were three states that I was interested in notifying the users of my app about:

  1. Is WiFi available on the device
  2. Is the WiFi enabled
  3. Is the WiFi connected to an access point

One of the features in Android is the concept of listeners. These are classes that allow your app to receive and process events based on the state of something on the device. For example there are listeners that allow you to monitor GPS updates or accelerometer changes. So the off I went to search for a listener for WiFi changes… well to my surprise there is no listener for WiFi state.

Not to be discouraged I set off in search of an alternative and that’s where the BroadcastReceiver comes into play. Android has a concept of sending off intent actions which you can register to receive. This is perfect for our situation as we can register for the broadcasts related to the WiFi state and within our receiver we can update our application.

Here is the code to create a receiver class and register it to receive WiFi state changes:

private class ConnectionChangeReceiver extends BroadcastReceiver {
public void onReceive( Context context, Intent intent ) {
Log.d(tag, "Inside Broadcast Reciever");
CheckWifiStatus();
}
}

private void RegisterWifiWatcher()
{
if(wifiWatcher == null)
wifiWatcher = new ConnectionChangeReceiver();

IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
intentFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
intentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
intentFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
registerReceiver(wifiWatcher, intentFilter);
}

One thing with BroadcastReceivers you need to be aware of is that they should be registered in the onResume() method and unregistered in the onPause() method. According to the documentation your application will not receive the broadcast if it is paused so unregistering the receiver helps with system overhead.

Another thing that is specific to broadcast receivers it that you need to know is that a receiver is only valid for the duration of the call to its onReceive() method. This means that you should not do any asynchronous work from within that method. Instead if you need to you can launch a service or send notifications through the notification manager.

NOTE: The broadcast intents that we receive for the different WiFi states have extras along with them that you can access to determine the different states of the WiFi connection. I have chosen to use a different method of testing states.

With that being said if you remember we wanted to check three states.

The first one is only needed to be checked on the start of our applicaiton. If the WiFi is not available on this device the I doubt it will become available at a later time. We simply create a WifiManager object and check if it is null – if it is then the device has no WiFi.

WifiManager wifiMgr = (WifiManager) this.getSystemService(Context.WIFI_SERVICE);
if(wifiMgr == null)
     Toast.makeText(this.getApplicationContext(), "No WiFi available on device.",Toast.LENGTH_LONG).show();

The second one is if the WiFi is enabled. Here we use the same WifiManager object and if it is not null we check to see if the WiFi is enabled.

if(wifiMgr.isEnabled())
     Toast.makeText(this.getApplicationContext(), "WiFi enabled.",Toast.LENGTH_LONG).show();

The last piece is to check if we have connectivity to an actual wireless access point. Remember that even though the wireless is enabled it may not be connected and we will not be able to send data.

This is a little more involved as we have to iterate through an array to find the WiFi connection then we can determine it’s state.

First we get a ConnecticityManager and with that we retrieve a NetworkInfo array. We then iterate this array looking for the NetworkInfo object for the WiFI after that we check if that object is connected, if so, we are ready to send data!

ConnectivityManager conMgr = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo[] netInf = conMgr.getAllNetworkInfo();
for(NetworkInfo inf : netInf){
    if(inf.getTypeName().contains("WIFI"))
    {
        if(inf.isConnected()){
            Toast.makeText(this.getApplicationContext(), "WiFi is connected.",Toast.LENGTH_LONG).show();

        }  
        else{
            Toast.makeText(this.getApplicationContext(), "WiFi NOT connected.",Toast.LENGTH_LONG).show();

        }
    }
}

There you have it. With this you should be able to detect the state of the WiFi!