What I want: when internet connection status changes from OFF to ON or vice-versa - I want to know about that immediately to stop/start a service even if the application isn't active. As pending intents may outlive the calling application, I think this is achievable.
I'm trying to use ConnectivityManager.registerNetworkCallback, the overloaded version taking PendingIntent, this way:
There is a broadcast receiver NetworkStatusReceiver that is supposed to receive intents related to network events:
class NetworkStatusReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
Toast.makeText(context, "something's changed", Toast.LENGTH_SHORT).show();
}
}
Register the receiver in AndroidManifest.xml:
<receiver android:name=".NetworkStatusReceiver"
android:enabled="true"
android:exported="true"/>
Finally make a pending intent and register it as a network callback:
val builder = NetworkRequest.Builder()
builder.addTransportType(NetworkCapabilitties.TRANSPORT_CELLULAR)
builder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
val networkRequest = builder.build()
val intent = Intent(context, NetworkStatusReceiver::class.java)
val pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0)
val connectivityManager = context.getSystemService(ConnectivityManager::class.java)
connectivityManager.registerNetworkCallback(networkRequest, pendingIntent)
The problem
When the internet connection is initially OFF - NetworkStatusReceiver receives the intent when it becomes ON. Even if the application has been killed. Ok, this way (OFF -> ON) it works. But! When the internet connection is active at the moment of registerNetworkCallback, NetworkStatusReceiver receives the intent instantly. I though that the callback is called only when something changes. But in this case it's called at once even if nothing changes. For that reason I can't track ON -> OFF event.
Any ideas, what I'm doing wrong? How to track ON -> OFF even this way? It seems that using registerNetworkCallback with PendingIntent isn't that popular, so the information about its usage is very scarce.
Is all you are trying to do is know when you have internet connectivity? If that's the case, you don't need to worry about the transport type but instead that you have a validated internet capable network available.
For internet you would use
NET_CAPABILITY_INTERNETand for validated (whether or not this network actually has connectivity) you would useNET_CAPABILITY_VALIDATED.You would then update your request to something like this:
You may want to also include
NET_CAPABILITY_NOT_METEREDin case you don't want to use metered connections or not.