M Peeran
06/09/2023, 7:22 AMKonstantin Kolchurin
06/09/2023, 7:30 AM@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 activityM Peeran
06/09/2023, 2:17 PM