@@ -26,57 +26,71 @@ import android.net.NetworkRequest.Builder
2626import android.os.Build.VERSION
2727import android.os.Build.VERSION_CODES
2828import androidx.core.content.getSystemService
29+ import androidx.tracing.Trace
30+ import androidx.tracing.trace
31+ import com.google.samples.apps.nowinandroid.core.network.Dispatcher
32+ import com.google.samples.apps.nowinandroid.core.network.NiaDispatchers.IO
2933import dagger.hilt.android.qualifiers.ApplicationContext
34+ import kotlinx.coroutines.CoroutineDispatcher
3035import kotlinx.coroutines.channels.awaitClose
3136import kotlinx.coroutines.flow.Flow
3237import kotlinx.coroutines.flow.callbackFlow
3338import kotlinx.coroutines.flow.conflate
39+ import kotlinx.coroutines.flow.flowOn
3440import javax.inject.Inject
3541
3642internal class ConnectivityManagerNetworkMonitor @Inject constructor(
3743 @ApplicationContext private val context : Context ,
44+ @Dispatcher(IO ) private val ioDispatcher : CoroutineDispatcher ,
3845) : NetworkMonitor {
3946 override val isOnline: Flow <Boolean > = callbackFlow {
40- val connectivityManager = context.getSystemService<ConnectivityManager >()
41- if (connectivityManager == null ) {
42- channel.trySend(false )
43- channel.close()
44- return @callbackFlow
45- }
47+ trace(" NetworkMonitor.callbackFlow" ) {
48+ val connectivityManager = context.getSystemService<ConnectivityManager >()
49+ if (connectivityManager == null ) {
50+ channel.trySend(false )
51+ channel.close()
52+ return @callbackFlow
53+ }
54+
55+ /* *
56+ * The callback's methods are invoked on changes to *any* network matching the [NetworkRequest],
57+ * not just the active network. So we can simply track the presence (or absence) of such [Network].
58+ */
59+ val callback = object : NetworkCallback () {
4660
47- /* *
48- * The callback's methods are invoked on changes to *any* network matching the [NetworkRequest],
49- * not just the active network. So we can simply track the presence (or absence) of such [Network].
50- */
51- val callback = object : NetworkCallback () {
61+ private val networks = mutableSetOf<Network >()
5262
53- private val networks = mutableSetOf<Network >()
63+ override fun onAvailable (network : Network ) {
64+ networks + = network
65+ channel.trySend(true )
66+ }
5467
55- override fun onAvailable (network : Network ) {
56- networks + = network
57- channel.trySend(true )
68+ override fun onLost (network : Network ) {
69+ networks - = network
70+ channel.trySend(networks.isNotEmpty())
71+ }
5872 }
5973
60- override fun onLost (network : Network ) {
61- networks - = network
62- channel.trySend(networks.isNotEmpty())
74+ trace(" NetworkMonitor.registerNetworkCallback" ) {
75+ val request = Builder ()
76+ .addCapability(NetworkCapabilities .NET_CAPABILITY_INTERNET )
77+ .build()
78+ connectivityManager.registerNetworkCallback(request, callback)
6379 }
64- }
6580
66- val request = Builder ()
67- .addCapability( NetworkCapabilities . NET_CAPABILITY_INTERNET )
68- .build()
69- connectivityManager.registerNetworkCallback(request, callback )
81+ /* *
82+ * Sends the latest connectivity status to the underlying channel.
83+ */
84+ channel.trySend( connectivityManager.isCurrentlyConnected() )
7085
71- /* *
72- * Sends the latest connectivity status to the underlying channel.
73- */
74- channel.trySend(connectivityManager.isCurrentlyConnected())
86+ Trace .endSection()
7587
76- awaitClose {
77- connectivityManager.unregisterNetworkCallback(callback)
88+ awaitClose {
89+ connectivityManager.unregisterNetworkCallback(callback)
90+ }
7891 }
7992 }
93+ .flowOn(ioDispatcher)
8094 .conflate()
8195
8296 @Suppress(" DEPRECATION" )
0 commit comments