Monitor connectivity status and connection metering

The ConnectivityManager provides an API that lets you request that the device connect to a network based on various conditions that include device capabilities and data transport options.

The callback implementation provides information to your app about the device's connection status as well as the capabilities of the currently connected network. The API lets you determine whether the device is currently connected to a network that satisfies your app's requirements.

Configure a network request

To specify the transport type of the network, such as Wi-Fi or cellular connection, and the currently connected network's capabilities, such as internet connection, you must configure a network request.

Declare a NetworkRequest that describes your app's network connection needs. The following code creates a request for a network that is connected to the internet and uses a Wi-Fi, ethernet, or cellular connection for the transport type.

private val networkRequest = NetworkRequest.Builder()
    .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
    .addTransportType(NetworkCapabilities.TRANSPORT_ETHERNET)
    .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
    .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
    .build()

Note that some connections can be significantly more expensive than others (for example, a mobile connection is typically expensive). Use NetworkCapabilities#NET_CAPABILITY_NOT_METERED to determine whether the connection is expensive. When on a metered connection, try to reduce your app's data consumption, or delay it until the device has a non-metered connection.

Configure a network callback

When you register the NetworkRequest with the ConnectivityManager, you must implement a NetworkCallback to receive notifications about changes in the connection status and network capabilities.

The most commonly implemented functions in the NetworkCallback include the following:

  • onAvailable() indicates that the device is connected to a new network that satisfies the capabilities and transport type requirements specified in the NetworkRequest.
  • onLost() indicates that the device has lost connection to the network.
  • onCapabilitiesChanged() indicates that the capabilities of the network have changed. The NetworkCapabilities object provides information about the current capabilities of the network.

private val networkCallback = object : ConnectivityManager.NetworkCallback() {
    override fun onAvailable(network: Network) {
        // Network is available for use.
    }

    // Network capabilities have changed for the network.
    override fun onCapabilitiesChanged(
        network: Network,
        networkCapabilities: NetworkCapabilities
    ) {
        val unmetered =
            networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
        if (!unmetered) {
            // Reduce data usage, or delay it until the network is unmetered.
        }
    }

    override fun onLost(network: Network) {
        // Lost network connection.
    }
}

Register for network updates

After you declare the NetworkRequest and NetworkCallback, use the requestNetwork() or registerNetworkCallback() functions to search for a network to connect from the device that satisfies the NetworkRequest. The status is then reported to the NetworkCallback.

val connectivityManager = getSystemService(ConnectivityManager::class.java)
connectivityManager.registerNetworkCallback(networkRequest, networkCallback)