-
-
Save iRYO400/5da269f4d5edbc365c952bdcbdfe6b68 to your computer and use it in GitHub Desktop.
| import android.content.Context | |
| import android.content.Context.CONNECTIVITY_SERVICE | |
| import android.net.ConnectivityManager | |
| import android.net.Network | |
| import android.net.NetworkCapabilities | |
| import android.net.NetworkRequest | |
| import androidx.lifecycle.Lifecycle | |
| import androidx.lifecycle.LifecycleObserver | |
| import androidx.lifecycle.LifecycleOwner | |
| import androidx.lifecycle.OnLifecycleEvent | |
| import timber.log.Timber | |
| class ConnectivityMonitor( | |
| context: Context, | |
| lifecycleOwner: LifecycleOwner, | |
| private val callback: (Boolean) -> Unit | |
| ) : LifecycleObserver { | |
| private var connectivityManager = | |
| context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager | |
| private val networkRequest = NetworkRequest.Builder() | |
| .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) | |
| .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR) | |
| .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) | |
| .addTransportType(NetworkCapabilities.TRANSPORT_ETHERNET) | |
| .addTransportType(NetworkCapabilities.TRANSPORT_VPN) | |
| .build() | |
| init { | |
| lifecycleOwner.lifecycle.addObserver(this) | |
| } | |
| @Suppress("unused") | |
| @OnLifecycleEvent(Lifecycle.Event.ON_START) | |
| fun onResume() { | |
| toggleConnectionState(connectivityManager.isDefaultNetworkActive) | |
| connectivityManager.registerNetworkCallback(networkRequest, networkCallback) | |
| } | |
| @Suppress("unused") | |
| @OnLifecycleEvent(Lifecycle.Event.ON_STOP) | |
| fun onPause() { | |
| connectivityManager.unregisterNetworkCallback(networkCallback) | |
| } | |
| private fun toggleConnectionState(isConnected: Boolean) = callback.invoke(isConnected) | |
| private val networkCallback = object : ConnectivityManager.NetworkCallback() { | |
| override fun onCapabilitiesChanged( | |
| network: Network, | |
| networkCapabilities: NetworkCapabilities | |
| ) { | |
| super.onCapabilitiesChanged(network, networkCapabilities) | |
| Timber.d("onCapabilitiesChanged") | |
| lastInternetConnectionCheck() | |
| } | |
| override fun onAvailable(network: Network) { | |
| super.onAvailable(network) | |
| Timber.d("onAvailable") | |
| lastInternetConnectionCheck() | |
| } | |
| override fun onLost(network: Network) { | |
| super.onLost(network) | |
| Timber.d("onLost") | |
| lastInternetConnectionCheck() | |
| } | |
| private fun lastInternetConnectionCheck() = | |
| connectivityManager.allNetworks.forEach { network -> | |
| network?.let { | |
| connectivityManager.getNetworkCapabilities(it) | |
| ?.let { networkCapabilities -> | |
| val netInternet = | |
| networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) | |
| val transportCellular = | |
| networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) | |
| val transportWifi = | |
| networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) | |
| val transportEthernet = | |
| networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) | |
| val transportVpn = | |
| networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN) | |
| val isConnected = netInternet || | |
| transportWifi || transportCellular || | |
| transportEthernet || transportVpn | |
| Timber.d("Connections State $isConnected netInternet: $netInternet, WiFi: $transportWifi, Cellular: $transportCellular, Ethernet: $transportEthernet, VPN: $transportVpn") | |
| toggleConnectionState(isConnected) | |
| } | |
| } | |
| } | |
| } | |
| } |
@krb449 That behavior is coming from lastInternetConnectionCheck(). As long as any of the variables transportCellular, ... is true, netInternet will be true and toggleConnectionState/isConnected will be true. I think that also explains @agvozditskiy observation.
For my project, I just included only netInternet in isConnected and so far I have a consistent behavior.
val isConnected = netInternet
// ||transportWifi || transportCellular || transportEthernet || transportVpn
@iRYO400 Thanks for the code
Hello guys, allNetworks array become empty (zero size) when the connection is lost and the callback is not triggered, so the last function should be:
private fun lastInternetConnectionCheck() {
if (connectivityManager.allNetworks.size == 0) {
toggleConnectionState(false)
} else {
connectivityManager.allNetworks.forEach { network ->
network?.let {
connectivityManager.getNetworkCapabilities(it)
?.let { networkCapabilities ->
val netInternet =
networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
val transportCellular =
networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
val transportWifi =
networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
val transportEthernet =
networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)
val transportVpn =
networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN)
val isConnected = netInternet ||
transportWifi || transportCellular ||
transportEthernet || transportVpn
Log.d("DEBUG", "Connections State $isConnected netInternet: $netInternet, WiFi: $transportWifi, Cellular: $transportCellular, Ethernet: $transportEthernet, VPN: $transportVpn")
toggleConnectionState(isConnected)
}
}
}
}
}
Seems this code is not working i have tried it but internet is not there then also private fun setListeners() {
ConnectivityMonitor(this, this) { isConnected ->
//TODO whatever you need
}
}
isConnected coming true
getting isConnected true even I disabled cellular network,