Created
October 3, 2024 15:56
-
-
Save rommansabbir/8c5783a8f1f5a0bf4510c96c7795eac9 to your computer and use it in GitHub Desktop.
Android: MonitorNetworkStatus in Jetpack Compose
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Checks if the current network is connected to the internet and validated. | |
* Validation indicates the network is functional (e.g., it can be used for browsing). | |
* | |
* @return True if the network is connected, has internet capability, and is validated; false otherwise. | |
*/ | |
private fun Context.isInternetFunctional(): Boolean { | |
val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager | |
val network = connectivityManager.activeNetwork | |
val networkCapabilities = connectivityManager.getNetworkCapabilities(network) | |
return networkCapabilities?.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) == true && | |
networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED) | |
} | |
/** | |
* A Composable function that monitors internet connectivity status in a lifecycle-aware manner. | |
* It uses ConnectivityManager.NetworkCallback to listen for network changes, ensuring the network is validated. | |
* | |
* @param lifecycleOwner The lifecycle owner to observe, typically the hosting activity or fragment. | |
* @param onNetworkStatusChanged A callback function that provides the current network status (true if the internet is functional). | |
*/ | |
@Composable | |
fun MonitorNetworkStatus( | |
lifecycleOwner: LifecycleOwner = LocalLifecycleOwner.current, | |
onNetworkStatusChanged: (Boolean) -> Unit | |
) { | |
val context = LocalContext.current | |
var isNetworkFunctional by remember { mutableStateOf(context.isInternetFunctional()) } | |
val connectivityManager = remember { | |
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager | |
} | |
DisposableEffect(lifecycleOwner) { | |
// Lifecycle observer to handle lifecycle events | |
val observer = LifecycleEventObserver { _, event -> | |
when (event) { | |
Lifecycle.Event.ON_RESUME -> { | |
Log.d("MonitorNetworkStatus", "ON_RESUME event triggered.") | |
try { | |
// Update the network status on resume | |
val currentNetworkStatus = context.isInternetFunctional() | |
if (isNetworkFunctional != currentNetworkStatus) { | |
isNetworkFunctional = currentNetworkStatus | |
Log.d("MonitorNetworkStatus", "Network validation state: $isNetworkFunctional") | |
onNetworkStatusChanged(isNetworkFunctional) | |
} | |
} catch (e: Exception) { | |
Log.e("MonitorNetworkStatus", "Exception checking network status: ${e.localizedMessage}", e) | |
} | |
} | |
else -> { | |
Log.d("MonitorNetworkStatus", "Unhandled lifecycle event: $event") | |
} | |
} | |
} | |
// NetworkCallback to listen for network changes | |
val networkCallback = object : ConnectivityManager.NetworkCallback() { | |
override fun onAvailable(network: Network) { | |
val networkCapabilities = connectivityManager.getNetworkCapabilities(network) | |
val isFunctional = | |
(networkCapabilities?.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) == true) && | |
networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED) | |
if (isFunctional != isNetworkFunctional) { | |
isNetworkFunctional = isFunctional | |
Log.d("MonitorNetworkStatus", "Network validation state changed: $isNetworkFunctional") | |
onNetworkStatusChanged(isNetworkFunctional) | |
} | |
} | |
override fun onLost(network: Network) { | |
if (isNetworkFunctional) { | |
isNetworkFunctional = false | |
Log.d("MonitorNetworkStatus", "Network connection lost.") | |
onNetworkStatusChanged(false) | |
} | |
} | |
override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) { | |
val isFunctional = networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) && | |
networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED) | |
if (isFunctional != isNetworkFunctional) { | |
isNetworkFunctional = isFunctional | |
Log.d("MonitorNetworkStatus", "Network capabilities changed: $isNetworkFunctional") | |
onNetworkStatusChanged(isNetworkFunctional) | |
} | |
} | |
} | |
// Register the network callback to listen for internet connectivity changes | |
val networkRequest = NetworkRequest.Builder() | |
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) | |
.build() | |
connectivityManager.registerNetworkCallback(networkRequest, networkCallback) | |
// Add the observer to the lifecycle | |
lifecycleOwner.lifecycle.addObserver(observer) | |
Log.d("MonitorNetworkStatus", "Observer added to lifecycle.") | |
// Cleanup on disposal | |
onDispose { | |
lifecycleOwner.lifecycle.removeObserver(observer) | |
connectivityManager.unregisterNetworkCallback(networkCallback) | |
Log.d("MonitorNetworkStatus", "Observer and network callback removed.") | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment