Skip to content

Instantly share code, notes, and snippets.

@Schadenfeude
Created April 11, 2023 11:52
Show Gist options
  • Save Schadenfeude/94ca620b5a28a7612758df67cfc72c98 to your computer and use it in GitHub Desktop.
Save Schadenfeude/94ca620b5a28a7612758df67cfc72c98 to your computer and use it in GitHub Desktop.
Connectivity Monitor (Android)
interface ConnectivityMonitor {
val isConnected: Boolean
val networkType: NetworkType
val isConnectedState: Flow<Boolean>
val networkTypeState: Flow<NetworkType>
}
import android.content.Context
import android.net.ConnectivityManager
import android.net.Network
import android.net.NetworkCapabilities
class ConnectivityMonitorImpl(appContext: Context) : ConnectivityMonitor {
private val connectivityManager = appContext.getSystemService(ConnectivityManager::class.java)
private val networkCallback = object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) =
connectivityManager.getNetworkCapabilities(network)?.let { networkCapabilities ->
updateConnectionStatus(networkCapabilities = networkCapabilities)
updateNetworkType(networkCapabilities = networkCapabilities)
} ?: run {
isConnectedState.value = true
}
override fun onLost(network: Network) {
// Do not check for NetworkCapabilities here, as they might be wrong.
// If we get this callback, we're certain that we've lost connection.
isConnectedState.value = false
networkTypeState.value = NetworkType.Unknown
}
override fun onCapabilitiesChanged(
network: Network,
networkCapabilities: NetworkCapabilities
) {
updateConnectionStatus(networkCapabilities = networkCapabilities)
updateNetworkType(networkCapabilities = networkCapabilities)
}
}
override val isConnected: Boolean
get() = isConnectedState.value
override val networkType: NetworkType
get() = networkTypeState.value
override val isConnectedState: StateFlow<Boolean> = MutableStateFlow(init = false)
override val networkTypeState: KmmState<NetworkType> = MutableStateFlow(init = NetworkType.Unknown)
init {
startMonitoring()
}
private fun startMonitoring() =
connectivityManager.registerDefaultNetworkCallback(networkCallback)
private fun updateConnectionStatus(networkCapabilities: NetworkCapabilities) {
val isConnected =
networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
isConnectedState.value = isConnected
}
private fun updateNetworkType(networkCapabilities: NetworkCapabilities) {
val networkType = when {
networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> NetworkType.WiFi
networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> NetworkType.Cellular
else -> NetworkType.Unknown
}
networkTypeState.value = networkType
}
}
enum class NetworkType { Unknown, Cellular, WiFi }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment