https://kotlinlang.org logo
m

M Peeran

06/09/2023, 7:22 AM
Hi everyone, I wanna know what approch you guys use to monitor internet connectivity on Android devices. I have used Lived data for this purpose in my apps but it is flaky, it doesn't detect correctly. Or maybe I am doing it the wrong way but I wanna know if there is a different or better way to achieve this. Thanks in advance!
not kotlin but kotlin colored 3
k

Konstantin Kolchurin

06/09/2023, 7:30 AM
Last time im use this solution:
Copy code
@Suppress("InjectDispatcher")
class NetworkMonitor(
    applicationContext: Context,
) : NetworkConnectivityService {
    private val connectivityManager = applicationContext.getSystemService(
        Context.CONNECTIVITY_SERVICE
    ) as ConnectivityManager

    override val networkStatus: Flow<NetworkStatus> = callbackFlow {
        val connectivityCallback = object : NetworkCallback() {
            override fun onAvailable(network: Network) {
                val isAvailable: NetworkStatus = pingToGoogle()
                trySend(isAvailable)
            }

            override fun onLosing(network: Network, maxMsToLive: Int) {
                trySend(OFFLINE)
            }

            override fun onLost(network: Network) {
                trySend(OFFLINE)
            }

            override fun onUnavailable() {
                trySend(OFFLINE)
            }
        }

        val request = NetworkRequest.Builder()
            .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
            .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
            .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
            .build()

        connectivityManager.registerNetworkCallback(request, connectivityCallback)

        awaitClose {
            connectivityManager.unregisterNetworkCallback(connectivityCallback)
        }
    }.distinctUntilChanged().flowOn(<http://Dispatchers.IO|Dispatchers.IO>)

    private fun pingToGoogle(): NetworkStatus {
        return try {
            Runtime.getRuntime().exec("ping -w -c 1 <http://google.com|google.com>").waitFor()
            ONLINE
        } catch (e: IOException) {
            Timber.e("NetworkMonitor ping failed: $e")
            OFFLINE
        } catch (e: InterruptedException) {
            Timber.e("NetworkMonitor ping failed: $e")
            OFFLINE
        }
    }
}

interface NetworkConnectivityService {
    val networkStatus: Flow<NetworkStatus>
}
Inject in VM and use on current screen or app in activity
m

M Peeran

06/09/2023, 2:17 PM
👍
4 Views