From fecab96e4ce13d08d37c13a5582a5fd78f1465ff Mon Sep 17 00:00:00 2001 From: Simon Marquis Date: Tue, 30 May 2023 23:06:40 +0200 Subject: [PATCH 1/2] Keep track of matching `Network`s inside `NetworkCallback` This will ensure the connectivity state remains synchronized with the `ConnectivityManager`. Fixes #714 --- .../util/ConnectivityManagerNetworkMonitor.kt | 47 +++++++++---------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/util/ConnectivityManagerNetworkMonitor.kt b/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/util/ConnectivityManagerNetworkMonitor.kt index b0bf9d820..d55520646 100644 --- a/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/util/ConnectivityManagerNetworkMonitor.kt +++ b/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/util/ConnectivityManagerNetworkMonitor.kt @@ -20,7 +20,8 @@ import android.content.Context import android.net.ConnectivityManager import android.net.ConnectivityManager.NetworkCallback import android.net.Network -import android.net.NetworkCapabilities +import android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET +import android.net.NetworkRequest import android.net.NetworkRequest.Builder import android.os.Build.VERSION import android.os.Build.VERSION_CODES @@ -44,36 +45,31 @@ class ConnectivityManagerNetworkMonitor @Inject constructor( } /** - * Sends the latest connectivity status to the underlying channel. - */ - fun update() { - channel.trySend(connectivityManager.isCurrentlyConnected()) - } - - /** - * The callback's methods are invoked on changes to *any* network, not just the active - * network. So to check for network connectivity, one must query the active network of the - * ConnectivityManager. + * The callback's methods are invoked on changes to *any* network matching the [NetworkRequest], + * not just the active network. So we can simply track the presence (or absence) of such [Network]. */ val callback = object : NetworkCallback() { - override fun onAvailable(network: Network) = update() - override fun onLost(network: Network) = update() + private val networks = mutableSetOf() - override fun onCapabilitiesChanged( - network: Network, - networkCapabilities: NetworkCapabilities, - ) = update() + override fun onAvailable(network: Network) { + networks += network + channel.trySend(true) + } + + override fun onLost(network: Network) { + networks -= network + channel.trySend(networks.isNotEmpty()) + } } - connectivityManager.registerNetworkCallback( - Builder() - .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) - .build(), - callback, - ) + val request = Builder().addCapability(NET_CAPABILITY_INTERNET).build() + connectivityManager.registerNetworkCallback(request, callback) - update() + /** + * Sends the latest connectivity status to the underlying channel. + */ + channel.trySend(connectivityManager.isCurrentlyConnected()) awaitClose { connectivityManager.unregisterNetworkCallback(callback) @@ -86,7 +82,8 @@ class ConnectivityManagerNetworkMonitor @Inject constructor( VERSION.SDK_INT >= VERSION_CODES.M -> activeNetwork ?.let(::getNetworkCapabilities) - ?.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) + ?.hasCapability(NET_CAPABILITY_INTERNET) + else -> activeNetworkInfo?.isConnected } ?: false } From 27154ef38a49e7c382ff3fc4d6eab5557a89da50 Mon Sep 17 00:00:00 2001 From: Simon Marquis Date: Sat, 3 Jun 2023 14:09:55 +0200 Subject: [PATCH 2/2] Apply changes from review comments --- .../core/data/util/ConnectivityManagerNetworkMonitor.kt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/util/ConnectivityManagerNetworkMonitor.kt b/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/util/ConnectivityManagerNetworkMonitor.kt index d55520646..c88125be8 100644 --- a/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/util/ConnectivityManagerNetworkMonitor.kt +++ b/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/util/ConnectivityManagerNetworkMonitor.kt @@ -20,7 +20,7 @@ import android.content.Context import android.net.ConnectivityManager import android.net.ConnectivityManager.NetworkCallback import android.net.Network -import android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET +import android.net.NetworkCapabilities import android.net.NetworkRequest import android.net.NetworkRequest.Builder import android.os.Build.VERSION @@ -63,7 +63,9 @@ class ConnectivityManagerNetworkMonitor @Inject constructor( } } - val request = Builder().addCapability(NET_CAPABILITY_INTERNET).build() + val request = Builder() + .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) + .build() connectivityManager.registerNetworkCallback(request, callback) /** @@ -82,7 +84,7 @@ class ConnectivityManagerNetworkMonitor @Inject constructor( VERSION.SDK_INT >= VERSION_CODES.M -> activeNetwork ?.let(::getNetworkCapabilities) - ?.hasCapability(NET_CAPABILITY_INTERNET) + ?.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) else -> activeNetworkInfo?.isConnected } ?: false