Last active
March 20, 2025 21:17
-
-
Save dylangrijalva/cb289de4e28dc8b6fdd11b9d84e56cd9 to your computer and use it in GitHub Desktop.
Helper classes to get the network state using built-in android APIs.
This file contains hidden or 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
| class AndroidNetworkModule( | |
| private val context: Context, | |
| private val dispatchers: CoroutineDispatchers, | |
| ) : NetworkModule { | |
| private val connectivityManager: ConnectivityManager | |
| get() = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager | |
| override fun stream(): Flow<NetworkState> { | |
| return callbackFlow { | |
| val callback = object : ConnectivityManager.NetworkCallback() { | |
| override fun onAvailable(network: Network) { | |
| val networkState = getNetworkState() | |
| trySend(networkState) | |
| } | |
| override fun onLost(network: Network) { | |
| val networkState = getNetworkState() | |
| trySend(networkState) | |
| } | |
| } | |
| val request = NetworkRequest.Builder() | |
| .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) | |
| .build() | |
| connectivityManager.registerNetworkCallback(request, callback) | |
| val networkState = getNetworkState() | |
| trySend(networkState) | |
| awaitClose { connectivityManager.unregisterNetworkCallback(callback) } | |
| }.flowOn(dispatchers.computation) | |
| } | |
| override fun getNetworkState(): NetworkState { | |
| try { | |
| if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) { | |
| val netInfo = connectivityManager.activeNetworkInfo | |
| ?: return NetworkState( | |
| isConnected = false, | |
| isInternetReachable = false, | |
| type = NetworkStateType.UNKNOWN | |
| ) | |
| val connectionType = getConnectionType(netInfo) | |
| return NetworkState( | |
| isConnected = connectionType.isDefined, | |
| isInternetReachable = netInfo.isConnected, | |
| type = connectionType | |
| ) | |
| } else { | |
| val network = connectivityManager.activeNetwork | |
| val isInternetReachable = network != null | |
| val connectionType = if (isInternetReachable) { | |
| val netCapabilities = connectivityManager.getNetworkCapabilities(network) | |
| getConnectionType(netCapabilities) | |
| } else { | |
| null | |
| } | |
| return NetworkState( | |
| isConnected = connectionType != null && connectionType.isDefined, | |
| isInternetReachable = isInternetReachable, | |
| type = connectionType ?: NetworkStateType.UNKNOWN | |
| ) | |
| } | |
| } catch (e: Exception) { | |
| throw Exception("Unable to access network information", e.cause) | |
| } | |
| } | |
| private fun getConnectionType(netInfo: NetworkInfo?): NetworkStateType { | |
| return when (netInfo?.type) { | |
| TYPE_MOBILE, | |
| TYPE_MOBILE_DUN -> NetworkStateType.CELLULAR | |
| TYPE_WIFI -> NetworkStateType.WIFI | |
| TYPE_BLUETOOTH -> NetworkStateType.BLUETOOTH | |
| TYPE_ETHERNET -> NetworkStateType.ETHERNET | |
| TYPE_WIMAX -> NetworkStateType.WIMAX | |
| TYPE_VPN -> NetworkStateType.VPN | |
| else -> NetworkStateType.UNKNOWN | |
| } | |
| } | |
| private fun getConnectionType(netCapabilities: NetworkCapabilities?): NetworkStateType = | |
| when { | |
| netCapabilities == null -> NetworkStateType.UNKNOWN | |
| netCapabilities.hasTransport(TRANSPORT_CELLULAR) -> NetworkStateType.CELLULAR | |
| netCapabilities.hasTransport(TRANSPORT_WIFI) || netCapabilities.hasTransport(TRANSPORT_WIFI_AWARE) -> NetworkStateType.WIFI | |
| netCapabilities.hasTransport(TRANSPORT_BLUETOOTH) -> NetworkStateType.BLUETOOTH | |
| netCapabilities.hasTransport(TRANSPORT_ETHERNET) -> NetworkStateType.ETHERNET | |
| netCapabilities.hasTransport(TRANSPORT_VPN) -> NetworkStateType.VPN | |
| else -> NetworkStateType.UNKNOWN | |
| } | |
| } |
This file contains hidden or 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
| data class NetworkState( | |
| val isConnected: Boolean, | |
| val isInternetReachable: Boolean, | |
| val type: NetworkStateType | |
| ) |
This file contains hidden or 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
| enum class NetworkStateType(val value: String) { | |
| NONE("NONE"), | |
| UNKNOWN("UNKNOWN"), | |
| CELLULAR("CELLULAR"), | |
| WIFI("WIFI"), | |
| BLUETOOTH("BLUETOOTH"), | |
| ETHERNET("ETHERNET"), | |
| WIMAX("WIMAX"), | |
| VPN("VPN"), | |
| OTHER("OTHER"); | |
| val isDefined: Boolean | |
| get() = this.value != "NONE" && this.value != "UNKNOWN" | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment