Wednesday, August 12, 2015

How to Determine Connectivity Status in Android — ConnectivityManager & NetworkCapabilities

While developing Android applications, a common use case is to schedule regular updates of application data from Internet resources, cache data, or execute long-running downloads. But if you aren't connected to the Internet, or the connection is too slow to complete your download, you should avoid waking the device or starting a network operation. So before you trigger any of these activities you need to check the connectivity status.

You can use the ConnectivityManager to check that you're actually connected to the Internet, and if so, what type of connection is in place (Wi‑Fi, cellular, ethernet, etc.). The Android docs are here: https://developer.android.com/reference/android/net/ConnectivityManager

Permissions

Make sure the following permission is declared in AndroidManifest.xml so your app can query connectivity state:

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

Legacy example (NetworkInfo)

The following snippet shows how to use ConnectivityManager to query the active network and determine if it has connectivity. This is the original/legacy approach and uses NetworkInfo (deprecated in API 29):

ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
boolean isConnected = activeNetwork != null && activeNetwork.isConnectedOrConnecting();

You can also check the type of the active network to determine whether it is Wi‑Fi:

boolean isWiFi = activeNetwork.getType() == ConnectivityManager.TYPE_WIFI;

Notes about the legacy approach:

  • NetworkInfo and isConnectedOrConnecting were commonly used in older Android versions, but NetworkInfo is deprecated starting in API level 29. Prefer the modern NetworkCapabilities approach on newer devices.

Modern approach (API 29+): NetworkCapabilities

On Android Q (API 29) and later, use NetworkCapabilities and getActiveNetwork() to inspect the currently active network in a more accurate way. NetworkCapabilities lets you check both transport type and capabilities such as NETCAPABILITYINTERNET and NETCAPABILITYVALIDATED.

ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
Network network = cm.getActiveNetwork(); // may be null
NetworkCapabilities nc = cm.getNetworkCapabilities(network);

boolean hasInternet = nc != null && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
boolean validated = nc != null && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
boolean isWifi = nc != null && nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI);

Explanation:

  • NETCAPABILITYINTERNET means the network can reach the Internet in principle.
  • NETCAPABILITYVALIDATED indicates the platform has validated that the network can actually reach the Internet (often more useful to decide whether to attempt network IO).
  • Use hasTransport(…) to detect TRANSPORTWIFI, TRANSPORTCELLULAR, TRANSPORTETHERNET, TRANSPORTVPN, etc.

Listening for changes: registerNetworkCallback

If you need to be notified of connectivity changes (rather than polling), register a NetworkCallback:

NetworkRequest request = new NetworkRequest.Builder()
        .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
        .build();

ConnectivityManager.NetworkCallback callback = new ConnectivityManager.NetworkCallback() {
    @Override
    public void onAvailable(Network network) {
        // network became available
    }

    @Override
    public void onLost(Network network) {
        // network lost
    }
};

cm.registerNetworkCallback(request, callback);
// Remember to unregister when appropriate: cm.unregisterNetworkCallback(callback);

Testing and troubleshooting

  • In the emulator you can simulate network conditions or disable the network.
  • Use adb to toggle airplane mode or modify network rules if needed.
  • Prefer checking NETCAPABILITYVALIDATED when you need a reliable indication that the network can reach the public Internet.

Summary

  • The original ConnectivityManager + NetworkInfo approach works on older devices but is deprecated (API 29+).
  • Use NetworkCapabilities.getNetworkCapabilities(getActiveNetwork()) and check capabilities and transports on modern Android.
  • Always declare ACCESSNETWORKSTATE in the manifest.

It's also possible to determine the type of Internet connection currently available. Device connectivity can be provided by mobile data, WiMAX, Wi‑Fi, and ethernet connections. By querying the type of the active network you can adjust behavior (for example, refresh rate or large downloads) based on bandwidth.

If "isWiFi" is true then the device is using Wi‑Fi connection. That's it. Happy coding.

References:

No comments: