|
|
|
|
@ -22,7 +22,6 @@ import android.net.ConnectivityManager.NetworkCallback
|
|
|
|
|
import android.net.Network
|
|
|
|
|
import android.net.NetworkCapabilities
|
|
|
|
|
import android.net.NetworkRequest
|
|
|
|
|
import android.net.NetworkRequest.Builder
|
|
|
|
|
import androidx.core.content.getSystemService
|
|
|
|
|
import androidx.tracing.trace
|
|
|
|
|
import com.google.samples.apps.nowinandroid.core.common.network.Dispatcher
|
|
|
|
|
@ -33,12 +32,13 @@ import kotlinx.coroutines.channels.awaitClose
|
|
|
|
|
import kotlinx.coroutines.flow.Flow
|
|
|
|
|
import kotlinx.coroutines.flow.callbackFlow
|
|
|
|
|
import kotlinx.coroutines.flow.conflate
|
|
|
|
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
|
|
|
|
import kotlinx.coroutines.flow.flowOn
|
|
|
|
|
import javax.inject.Inject
|
|
|
|
|
|
|
|
|
|
internal class ConnectivityManagerNetworkMonitor @Inject constructor(
|
|
|
|
|
@ApplicationContext private val context: Context,
|
|
|
|
|
@Dispatcher(IO) private val ioDispatcher: CoroutineDispatcher,
|
|
|
|
|
@param:ApplicationContext private val context: Context,
|
|
|
|
|
@param:Dispatcher(IO) private val ioDispatcher: CoroutineDispatcher,
|
|
|
|
|
) : NetworkMonitor {
|
|
|
|
|
override val isOnline: Flow<Boolean> = callbackFlow {
|
|
|
|
|
trace("NetworkMonitor.callbackFlow") {
|
|
|
|
|
@ -69,8 +69,12 @@ internal class ConnectivityManagerNetworkMonitor @Inject constructor(
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
trace("NetworkMonitor.registerNetworkCallback") {
|
|
|
|
|
val request = Builder()
|
|
|
|
|
val request = NetworkRequest.Builder()
|
|
|
|
|
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
|
|
|
|
|
.addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
|
|
|
|
|
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
|
|
|
|
|
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
|
|
|
|
|
.addTransportType(NetworkCapabilities.TRANSPORT_ETHERNET)
|
|
|
|
|
.build()
|
|
|
|
|
connectivityManager.registerNetworkCallback(request, callback)
|
|
|
|
|
}
|
|
|
|
|
@ -87,9 +91,31 @@ internal class ConnectivityManagerNetworkMonitor @Inject constructor(
|
|
|
|
|
}
|
|
|
|
|
.flowOn(ioDispatcher)
|
|
|
|
|
.conflate()
|
|
|
|
|
.distinctUntilChanged()
|
|
|
|
|
|
|
|
|
|
private fun ConnectivityManager.isCurrentlyConnected(): Boolean {
|
|
|
|
|
val networkCapabilities = getNetworkCapabilities(activeNetwork) ?: return false
|
|
|
|
|
return networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
|
|
|
|
|
val network = activeNetwork ?: return false
|
|
|
|
|
val capabilities = getNetworkCapabilities(network) ?: return false
|
|
|
|
|
|
|
|
|
|
return hasInternetCapability(capabilities) &&
|
|
|
|
|
isValidated(capabilities) &&
|
|
|
|
|
hasSupportedTransport(capabilities)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun hasInternetCapability(capabilities: NetworkCapabilities): Boolean {
|
|
|
|
|
return capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun isValidated(capabilities: NetworkCapabilities): Boolean {
|
|
|
|
|
return capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun hasSupportedTransport(capabilities: NetworkCapabilities): Boolean {
|
|
|
|
|
val supportedTransports = setOf(
|
|
|
|
|
NetworkCapabilities.TRANSPORT_WIFI,
|
|
|
|
|
NetworkCapabilities.TRANSPORT_CELLULAR,
|
|
|
|
|
NetworkCapabilities.TRANSPORT_ETHERNET,
|
|
|
|
|
)
|
|
|
|
|
return supportedTransports.any(capabilities::hasTransport)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|