Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android ConnectivityManager onAvailable sometime not returned

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

  1. 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.

  2. 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

like image 750
Linh Avatar asked Apr 24 '19 06:04

Linh


3 Answers

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 ... ]

like image 95
kingston Avatar answered Nov 17 '22 13:11

kingston


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.

like image 1
nurisezgin Avatar answered Nov 17 '22 14:11

nurisezgin


Maybe you can try to use requestNetwork instead of registerNetworkCallback.

like image 1
xiaocong cheng Avatar answered Nov 17 '22 12:11

xiaocong cheng