|
|
|
@ -30,61 +30,61 @@ import kotlinx.coroutines.channels.awaitClose
|
|
|
|
|
import kotlinx.coroutines.flow.Flow
|
|
|
|
|
import kotlinx.coroutines.flow.callbackFlow
|
|
|
|
|
import kotlinx.coroutines.flow.conflate
|
|
|
|
|
import Kotlinx.coroutines.flow.flowOf
|
|
|
|
|
import javax.inject.Inject
|
|
|
|
|
|
|
|
|
|
class ConnectivityManagerNetworkMonitor @Inject constructor(
|
|
|
|
|
@ApplicationContext private val context: Context,
|
|
|
|
|
) : NetworkMonitor {
|
|
|
|
|
override val isOnline: Flow<Boolean> = callbackFlow {
|
|
|
|
|
override val isOnline: Flow<Boolean> {
|
|
|
|
|
val connectivityManager = context.getSystemService<ConnectivityManager>()
|
|
|
|
|
?: return flowOf(false)
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The callback's methods are invoked on changes to *any* network, not just the active
|
|
|
|
|
* network. So to check for network connectivity, one must query the active network of the
|
|
|
|
|
* ConnectivityManager.
|
|
|
|
|
*/
|
|
|
|
|
val callback = object : NetworkCallback() {
|
|
|
|
|
override fun onAvailable(network: Network) {
|
|
|
|
|
channel.trySend(connectivityManager.isCurrentlyConnected())
|
|
|
|
|
}
|
|
|
|
|
return callbackFlow {
|
|
|
|
|
|
|
|
|
|
override fun onLost(network: Network) {
|
|
|
|
|
channel.trySend(connectivityManager.isCurrentlyConnected())
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* The callback's methods are invoked on changes to *any* network, not just the active
|
|
|
|
|
* network. So to check for network connectivity, one must query the active network of the
|
|
|
|
|
* ConnectivityManager.
|
|
|
|
|
*/
|
|
|
|
|
val callback = object : NetworkCallback() {
|
|
|
|
|
override fun onAvailable(network: Network) {
|
|
|
|
|
channel.trySend(connectivityManager.isCurrentlyConnected())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
override fun onLost(network: Network) {
|
|
|
|
|
channel.trySend(connectivityManager.isCurrentlyConnected())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
override fun onCapabilitiesChanged(
|
|
|
|
|
network: Network,
|
|
|
|
|
networkCapabilities: NetworkCapabilities,
|
|
|
|
|
) {
|
|
|
|
|
channel.trySend(connectivityManager.isCurrentlyConnected())
|
|
|
|
|
override fun onCapabilitiesChanged(
|
|
|
|
|
network: Network,
|
|
|
|
|
networkCapabilities: NetworkCapabilities,
|
|
|
|
|
) {
|
|
|
|
|
channel.trySend(connectivityManager.isCurrentlyConnected())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
connectivityManager?.registerNetworkCallback(
|
|
|
|
|
Builder()
|
|
|
|
|
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
|
|
|
|
|
.build(),
|
|
|
|
|
callback,
|
|
|
|
|
)
|
|
|
|
|
connectivityManager.registerNetworkCallback(
|
|
|
|
|
Builder()
|
|
|
|
|
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
|
|
|
|
|
.build(),
|
|
|
|
|
callback,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
channel.trySend(connectivityManager.isCurrentlyConnected())
|
|
|
|
|
channel.trySend(connectivityManager.isCurrentlyConnected())
|
|
|
|
|
|
|
|
|
|
awaitClose {
|
|
|
|
|
connectivityManager?.unregisterNetworkCallback(callback)
|
|
|
|
|
awaitClose {
|
|
|
|
|
connectivityManager.unregisterNetworkCallback(callback)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
.conflate()
|
|
|
|
|
.conflate()
|
|
|
|
|
|
|
|
|
|
@Suppress("DEPRECATION")
|
|
|
|
|
private fun ConnectivityManager?.isCurrentlyConnected() = when (this) {
|
|
|
|
|
null -> false
|
|
|
|
|
else -> when {
|
|
|
|
|
VERSION.SDK_INT >= VERSION_CODES.M ->
|
|
|
|
|
activeNetwork
|
|
|
|
|
?.let(::getNetworkCapabilities)
|
|
|
|
|
?.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
|
|
|
|
|
?: false
|
|
|
|
|
else -> activeNetworkInfo?.isConnected ?: false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
private fun ConnectivityManager.isCurrentlyConnected() = when {
|
|
|
|
|
VERSION.SDK_INT >= VERSION_CODES.M ->
|
|
|
|
|
activeNetwork
|
|
|
|
|
?.let(::getNetworkCapabilities)
|
|
|
|
|
?.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
|
|
|
|
|
else -> activeNetworkInfo?.isConnected
|
|
|
|
|
} ?: false
|
|
|
|
|
}
|
|
|
|
|