Open yikeng opened 10 months ago
Is there an existing issue for this?
- [X] I have searched the existing issues
Is there a StackOverflow question about this issue?
- [X] I have searched StackOverflow
What happened?
When an app goes to the background, onBlockedStatusChanged is called with true and then called with false when it comes back to the foreground. The function onAvailable isn't called in this case.
When blocked = true, The app cannot access the network; When blocked = false, The app can access the network.
In this scenario, NetworkMonitor.isOnline is not changed!
code :
` class ConnectivityManagerNetworkMonitor @Inject constructor( @ApplicationContext private val context: Context, ) : NetworkMonitor { override val isOnline: Flow
= callbackFlow { val connectivityManager = context.getSystemService () if (connectivityManager == null) { channel.trySend(false) channel.close() return@callbackFlow } /** * The callback's methods are invoked on changes to *any* network matching the [NetworkRequest], * not just the active network. So we can simply track the presence (or absence) of such [Network]. */ val callback = object : NetworkCallback() { private val networks = mutableSetOf<Network>() override fun onAvailable(network: Network) { networks += network channel.trySend(true) Timber.i("onAvailable:${networks.isNotEmpty()}") } override fun onLost(network: Network) { networks -= network channel.trySend(networks.isNotEmpty()) Timber.i("onLost:${networks.isNotEmpty()}") } override fun onCapabilitiesChanged( network: Network, networkCapabilities: NetworkCapabilities ) { Timber.i("onCapabilitiesChanged:${network}, ${networkCapabilities.toString()}") } override fun onBlockedStatusChanged(network: Network, blocked: Boolean) { Timber.i("onCapabilitiesChanged:${network}, blocked = $blocked") } } val request = Builder() .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) .build() connectivityManager.registerNetworkCallback(request, callback) /** * Sends the latest connectivity status to the underlying channel. */ channel.trySend(connectivityManager.isCurrentlyConnected()) awaitClose { connectivityManager.unregisterNetworkCallback(callback) } } .conflate()
}
`
Relevant logcat output
No response
Code of Conduct
- [X] I agree to follow this project's Code of Conduct
Is there an existing issue for this?
- [X] I have searched the existing issues
Is there a StackOverflow question about this issue?
- [X] I have searched StackOverflow
What happened?
When an app goes to the background, onBlockedStatusChanged is called with true and then called with false when it comes back to the foreground. The function onAvailable isn't called in this case.
When blocked = true, The app cannot access the network; When blocked = false, The app can access the network.
In this scenario, NetworkMonitor.isOnline is not changed!
code :
` class ConnectivityManagerNetworkMonitor @Inject constructor( @ApplicationContext private val context: Context, ) : NetworkMonitor { override val isOnline: Flow
= callbackFlow { val connectivityManager = context.getSystemService () if (connectivityManager == null) { channel.trySend(false) channel.close() return@callbackFlow } /** * The callback's methods are invoked on changes to *any* network matching the [NetworkRequest], * not just the active network. So we can simply track the presence (or absence) of such [Network]. */ val callback = object : NetworkCallback() { private val networks = mutableSetOf<Network>() override fun onAvailable(network: Network) { networks += network channel.trySend(true) Timber.i("onAvailable:${networks.isNotEmpty()}") } override fun onLost(network: Network) { networks -= network channel.trySend(networks.isNotEmpty()) Timber.i("onLost:${networks.isNotEmpty()}") } override fun onCapabilitiesChanged( network: Network, networkCapabilities: NetworkCapabilities ) { Timber.i("onCapabilitiesChanged:${network}, ${networkCapabilities.toString()}") } override fun onBlockedStatusChanged(network: Network, blocked: Boolean) { Timber.i("onCapabilitiesChanged:${network}, blocked = $blocked") } } val request = Builder() .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) .build() connectivityManager.registerNetworkCallback(request, callback) /** * Sends the latest connectivity status to the underlying channel. */ channel.trySend(connectivityManager.isCurrentlyConnected()) awaitClose { connectivityManager.unregisterNetworkCallback(callback) } } .conflate()
}
`
Relevant logcat output
No response
Code of Conduct
- [X] I agree to follow this project's Code of Conduct
Indeed, I've been able to reproduce this by configuring the device into forced idle mode:
adb shell dumpsys deviceidle force-idle
Then, locking the device or going to background will trigger onBlockedStatusChanged(blocked=true)
.
And finally, resuming the app will result in onAvailable()
(not always) and onBlockedStatusChanged(blocked=false)
.
I'm not 100% sure what a "blocked" network implies: does it put the network calls in standby, or are they immediately stopped?
If we were to support this, I suppose this simple code could be added to the NetworkCallback
:
override fun onBlockedStatusChanged(network: Network, blocked: Boolean) {
if (blocked) networks -= network else networks += network
channel.trySend(networks.isNotEmpty())
}
Indeed, I've been able to reproduce this by configuring the device into forced idle mode:
adb shell dumpsys deviceidle force-idle
Then, locking the device or going to background will trigger
onBlockedStatusChanged(blocked=true)
. And finally, resuming the app will result inonAvailable()
(not always) andonBlockedStatusChanged(blocked=false)
.I'm not 100% sure what a "blocked" network implies: does it put the network calls in standby, or are they immediately stopped? If we were to support this, I suppose this simple code could be added to the
NetworkCallback
:override fun onBlockedStatusChanged(network: Network, blocked: Boolean) { if (blocked) networks -= network else networks += network channel.trySend(networks.isNotEmpty()) }
Thank you!
I think the "blocked" network means the network are immediately stopped, because the tcp connection(in my app) was immediately disconnected.
Is there an existing issue for this?
Is there a StackOverflow question about this issue?
What happened?
When an app goes to the background, onBlockedStatusChanged is called with true and then called with false when it comes back to the foreground. The function onAvailable isn't called in this case.
When blocked = true, The app cannot access the network; When blocked = false, The app can access the network.
In this scenario, NetworkMonitor.isOnline is not changed!
code :
` class ConnectivityManagerNetworkMonitor @Inject constructor( @ApplicationContext private val context: Context, ) : NetworkMonitor { override val isOnline: Flow = callbackFlow {
val connectivityManager = context.getSystemService()
if (connectivityManager == null) {
channel.trySend(false)
channel.close()
return@callbackFlow
}
}
`
Relevant logcat output
No response
Code of Conduct