Skip to content

Instantly share code, notes, and snippets.

@rommansabbir
Created October 3, 2024 15:56
Show Gist options
  • Save rommansabbir/8c5783a8f1f5a0bf4510c96c7795eac9 to your computer and use it in GitHub Desktop.
Save rommansabbir/8c5783a8f1f5a0bf4510c96c7795eac9 to your computer and use it in GitHub Desktop.
Android: MonitorNetworkStatus in Jetpack Compose
/**
* 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