How do I see if Wi-Fi is connected on Android?

Viewed 250194

I don't want my user to even try downloading something unless they have Wi-Fi connected. However, I can only seem to be able to tell if Wi-Fi is enabled, but they could still have a 3G connection.

android.net.wifi.WifiManager m = (WifiManager) getSystemService(WIFI_SERVICE);
android.net.wifi.SupplicantState s = m.getConnectionInfo().getSupplicantState();
NetworkInfo.DetailedState state = WifiInfo.getDetailedStateOf(s);
if (state != NetworkInfo.DetailedState.CONNECTED) {
    return false;
}

However, the state is not what I would expect. Even though Wi-Fi is connected, I am getting OBTAINING_IPADDR as the state.

24 Answers

The NetworkInfo class is deprecated as of API level 29, along with the related access methods like ConnectivityManager#getNetworkInfo() and ConnectivityManager#getActiveNetworkInfo().

The documentation now suggests people to use the ConnectivityManager.NetworkCallback API for asynchronized callback monitoring, or use ConnectivityManager#getNetworkCapabilities or ConnectivityManager#getLinkProperties for synchronized access of network information

Callers should instead use the ConnectivityManager.NetworkCallback API to learn about connectivity changes, or switch to use ConnectivityManager#getNetworkCapabilities or ConnectivityManager#getLinkProperties to get information synchronously.


To check if WiFi is connected, here's the code that I use:

Kotlin:

val connMgr = applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager?
connMgr?: return false
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    val network: Network = connMgr.activeNetwork ?: return false
    val capabilities = connMgr.getNetworkCapabilities(network)
    return capabilities != null && capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
} else {
    val networkInfo = connMgr.activeNetworkInfo ?: return false
    return networkInfo.isConnected && networkInfo.type == ConnectivityManager.TYPE_WIFI
}

Java:

ConnectivityManager connMgr = (ConnectivityManager) getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
if (connMgr == null) {
    return false;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    Network network = connMgr.getActiveNetwork();
    if (network == null) return false;
    NetworkCapabilities capabilities = connMgr.getNetworkCapabilities(network);
    return capabilities != null && capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI);
} else {
    NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
    return networkInfo.isConnected() && networkInfo.getType() == ConnectivityManager.TYPE_WIFI;
}

Remember to also add permission ACCESS_NETWORK_STATE to your Manifest file.

Many of answers use deprecated code, or code available on higer API versions. Now I use something like this

ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        if(connectivityManager != null) {
            for (Network net : connectivityManager.getAllNetworks()) {
                NetworkCapabilities nc = connectivityManager.getNetworkCapabilities(net);
                if (nc != null && nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
                        && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET))
                    return true;
            }
        }
        return false;

The following code (in Kotlin) works from API 21 until at least current API version (API 29). The function getWifiState() returns one of 3 possible values for the WiFi network state: Disable, EnabledNotConnected and Connected that were defined in an enum class. This allows to take more granular decisions like informing the user to enable WiFi or, if already enabled, to connect to one of the available networks. But if all that is needed is a boolean indicating if the WiFi interface is connected to a network, then the other function isWifiConnected() will give you that. It uses the previous one and compares the result to Connected.

It's inspired in some of the previous answers but trying to solve the problems introduced by the evolution of Android API's or the slowly increasing availability of IP V6. The trick was to use:

wifiManager.connectionInfo.bssid != null 

instead of:

  1. getIpAddress() == 0 that is only valid for IP V4 or
  2. getNetworkId() == -1 that now requires another special permission (Location)

According to the documentation: https://developer.android.com/reference/kotlin/android/net/wifi/WifiInfo.html#getbssid it will return null if not connected to a network. And even if we do not have permission to get the real value, it will still return something other than null if we are connected.

Also have the following in mind:

On releases before android.os.Build.VERSION_CODES#N, this object should only be obtained from an Context#getApplicationContext(), and not from any other derived context to avoid memory leaks within the calling process.

In the Manifest, do not forget to add:

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>

Proposed code is:

class MyViewModel(application: Application) : AndroidViewModel(application) {

   // Get application context
    private val myAppContext: Context = getApplication<Application>().applicationContext

   // Define the different possible states for the WiFi Connection
    internal enum class WifiState {
        Disabled,               // WiFi is not enabled
        EnabledNotConnected,    // WiFi is enabled but we are not connected to any WiFi network
        Connected,              // Connected to a WiFi network
    }

    // Get the current state of the WiFi network
    private fun getWifiState() : WifiState {

        val wifiManager : WifiManager = myAppContext.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager

        return if (wifiManager.isWifiEnabled) {
                    if (wifiManager.connectionInfo.bssid != null)
                        WifiState.Connected
                    else
                        WifiState.EnabledNotConnected
               } else {
                    WifiState.Disabled
               }
    }

    // Returns true if we are connected to a WiFi network
    private fun isWiFiConnected() : Boolean {
        return (getWifiState() == WifiState.Connected)
    }
}

This works for Android devices before and after Q

fun isWifiConnected(context: Context):Boolean {
    val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
             val capabilities = cm.getNetworkCapabilities(cm.activeNetwork)
             capabilities?.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)==true
        } else {
            val activeNetwork: NetworkInfo? = cm.activeNetworkInfo
            activeNetwork?.typeName?.contains("wifi",ignoreCase = true)?:false
        }
}

Similar to @Jason Knight answer, but in Kotlin way:

val connManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val mWifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI)

if (mWifi.isConnected) {
     // Do whatever
}

Try

wifiManager.getConnectionInfo().getIpAddress()

This returns 0 until the device has a usable connection (on my machine, a Samsung SM-T280, Android 5.1.1).

Add this for JAVA:

public boolean CheckWifiConnection() {
        ConnectivityManager conMgr = (ConnectivityManager) getSystemService (Context.CONNECTIVITY_SERVICE);
        if (conMgr.getActiveNetworkInfo() != null
                && conMgr.getActiveNetworkInfo().isAvailable()
                && conMgr.getActiveNetworkInfo().isConnected()) {
            return true;
        } else {
            return false;
        }
    }

in Manifest file add the following permissions:

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

Kind of old a question but this is what i use. requires min api level 21 also takes in consideration deprecated Networkinfo apis.

boolean isWifiConn = false;
    ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        Network network = connMgr.getActiveNetwork();
        if (network == null) return false;
        NetworkCapabilities capabilities = connMgr.getNetworkCapabilities(network);
        if(capabilities != null && capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)){
            isWifiConn = true;
            Toast.makeText(context,"Wifi connected Api >= "+Build.VERSION_CODES.M,Toast.LENGTH_LONG).show();
        }else{
            Toast.makeText(context,"Wifi not connected Api >= "+Build.VERSION_CODES.M,Toast.LENGTH_LONG).show();
        }
    } else {
        for (Network network : connMgr.getAllNetworks()) {
            NetworkInfo networkInfo = connMgr.getNetworkInfo(network);
            if (networkInfo.getType() == ConnectivityManager.TYPE_WIFI && networkInfo.isConnected()) {
                isWifiConn = true;
                Toast.makeText(context,"Wifi connected ",Toast.LENGTH_LONG).show();
                break;
            }else{
                Toast.makeText(context,"Wifi not connected ",Toast.LENGTH_LONG).show();
            }
        }
    }
    return isWifiConn;
val wifi = context!!.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager?        
         if (wifi!!.isWifiEnabled) 
              //do action here
    
         else 
             //do action here
    
        
                    

This works with the latest versions of android:

fun getConnectionType(context: Context): ConnectivityType {
    var result = NONE
    val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager?
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (cm != null) {
            val capabilities = cm.getNetworkCapabilities(cm.activeNetwork)
            if (capabilities != null) {
                when {
                    capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> {
                        result = WIFI
                    }
                    capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> {
                        result = MOBILE_DATA
                    }
                    capabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN) -> {
                        result = VPN
                    }
                }
            }
        }
    } else {
        if (cm != null) {
            val activeNetwork = cm.activeNetworkInfo
            if (activeNetwork != null) {
                // connected to the internet
                when (activeNetwork.type) {
                    ConnectivityManager.TYPE_WIFI -> {
                        result = WIFI
                    }
                    ConnectivityManager.TYPE_MOBILE -> {
                        result = MOBILE_DATA
                    }
                    ConnectivityManager.TYPE_VPN -> {
                        result = VPN
                    }
                }
            }
        }
    }
    return result
}

enum class ConnectivityType {
    NONE,
    MOBILE_DATA,
    WIFI,
    VPN,
}

And in the manifest:

    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Related