We use the Android ConnectivityManager
to listen for internet connection changes inside our app as follows.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
...
ConnectionStateMonitor().enable(this)
}
class ConnectionStateMonitor : NetworkCallback() {
private val networkRequest: NetworkRequest = NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI).build()
fun enable(context: Context) {
val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
connectivityManager.registerNetworkCallback(networkRequest, this)
}
override fun onAvailable(network: Network) {
Log.i(TAG, "onAvailable ")
}
override fun onLost(network: Network?) {
super.onLost(network)
Log.i(TAG, "onLost ")
}
}
}
This implementation is working well except for two issues we've encountered
If we connect to the internet by using both wifi and mobile data and turn off wifi sometimes the onLost()
callback is fired followed by onAvailable()
, as expected, but in other instances only onLost()
is fired which is incorrect.
If we don't have internet connection and open the app onLost()
is not fired, however if we have internet connection and open the app onAvailable()
is fired.
Any help, suggestions, workarounds or another approaches to detect internet connection changes reliably would really be appreciated.
Tested on Xioami A2 (Android 9), OnePlus (Android 9)
DEMO project
https://github.com/PhanVanLinh/AndroidNetworkChangeReceiver
I have used your project and I added another method: onCapabilitiesChanged
. I started with the flight mode ebabled and then I turned off and then on again. These are the logs:
onAvailable 632
onCapabilitiesChanged 632 [ Transports: CELLULAR ...]
onAvailable 632
onCapabilitiesChanged 632 [ Transports: CELLULAR ...]
onAvailable 632
onCapabilitiesChanged 632 [ Transports: CELLULAR ...]
onCapabilitiesChanged 632 [ Transports: CELLULAR ...]
onCapabilitiesChanged 632 [ Transports: CELLULAR ...]
onAvailable 633
onCapabilitiesChanged 633 [ Transports: WIFI ...] onAvailable 633 onCapabilitiesChanged 633 [ Transports: WIFI ...]
onAvailable 633
onCapabilitiesChanged 633 [ Transports: WIFI ...]
onCapabilitiesChanged 633 [ Transports: WIFI ...]
onCapabilitiesChanged 633 [ Transports: WIFI ...]
onCapabilitiesChanged 633 [ Transports: WIFI ...]
onCapabilitiesChanged 633 [ Transports: WIFI ...]
onCapabilitiesChanged 633 [ Transports: WIFI ...]
onLost 632
onLost 632
onLost 632
onLost 633
onLost 633
onLost 633
onAvailable 634
onCapabilitiesChanged 634 [ Transports: CELLULAR ...]
onAvailable 634
onCapabilitiesChanged 634 [ Transports: CELLULAR ...]
onAvailable 634
onCapabilitiesChanged 634 [ Transports: CELLULAR ...]
onCapabilitiesChanged 634 [ Transports: CELLULAR ...]
onCapabilitiesChanged 634 [ Transports: CELLULAR ...]
onCapabilitiesChanged 634 [ Transports: CELLULAR ...]
onAvailable 635
onCapabilitiesChanged 635 [ Transports: WIFI ...]
onAvailable 635
onCapabilitiesChanged 635 [ Transports: WIFI ...]
onAvailable 635
onCapabilitiesChanged 635 [ Transports: WIFI ...]
onCapabilitiesChanged 635 [ Transports: WIFI ...]
onCapabilitiesChanged 635 [ Transports: WIFI ...]
onCapabilitiesChanged 635 [ Transports: WIFI ...]
onLost 634
onLost 634
onLost 634
onCapabilitiesChanged 635 [ Transports: WIFI ...]
onCapabilitiesChanged 635 [ Transports: WIFI ...]
As you can see the LOST
is for the cellular transport while the AVAILABLE
is for the WiFi
Following your use case (enable wifi, enable mobiledata, disable wifi data, enable wifi, disable wifi) this is what I get.
onAvailable 640
onCapabilitiesChanged 640 [ Transports: WIFI ... ]
onAvailable 640
onCapabilitiesChanged 640 [ Transports: WIFI ... ]
onCapabilitiesChanged 640 [ Transports: WIFI ... ]
onCapabilitiesChanged 640 [ Transports: WIFI ... ]
onCapabilitiesChanged 640 [ Transports: WIFI ... ]
onCapabilitiesChanged 640 [ Transports: WIFI ... ]
onLost 640
onLost 640
onAvailable 641
onCapabilitiesChanged 641 [ Transports: CELLULAR ... ]
onAvailable 641
onCapabilitiesChanged 641 [ Transports: CELLULAR ... ]
onCapabilitiesChanged 641 [ Transports: CELLULAR ... ]
onCapabilitiesChanged 641 [ Transports: CELLULAR ... ]
onAvailable 642
onCapabilitiesChanged 642 [ Transports: WIFI ... ]
onAvailable 642
onCapabilitiesChanged 642 [ Transports: WIFI ... ]
onCapabilitiesChanged 642 [ Transports: WIFI ... ]
onCapabilitiesChanged 642 [ Transports: WIFI ... ]
onCapabilitiesChanged 642 [ Transports: WIFI ... ]
onCapabilitiesChanged 642 [ Transports: WIFI ... ]
onLost 641
onLost 641
onLost 642
onLost 642
onAvailable 643
onCapabilitiesChanged 643 [ Transports: CELLULAR ... ]
onAvailable 643
onCapabilitiesChanged 643 [ Transports: CELLULAR ... ]
onCapabilitiesChanged 643 [ Transports: CELLULAR ... ]
onCapabilitiesChanged 643 [ Transports: CELLULAR ... ]
Broadcast receiver definition on AndroidManifest has changed a bit. You can find appropriate description on here.
You have already implemented this way but anyhow I would like add Network callback class references as a reference point.
Maybe you can try to use requestNetwork
instead of registerNetworkCallback
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With