@@ -5,8 +5,8 @@ import android.content.Context
55import android.net.ConnectivityManager
66import android.net.Network
77import android.net.NetworkCapabilities
8- import android.net.NetworkRequest
98import android.net.wifi.WifiInfo
9+ import android.net.wifi.WifiManager
1010import android.os.Build
1111import kotlinx.coroutines.ExperimentalCoroutinesApi
1212import kotlinx.coroutines.channels.awaitClose
@@ -24,31 +24,41 @@ import net.kuama.wifiMonitor.WifiListener
2424 * From now on, to observe connectivity changes we should register a [ConnectivityManager.NetworkCallback] implementation.
2525 */
2626@TargetApi(Build .VERSION_CODES .Q )
27- internal class AndroidQWifiListener : WifiListener {
27+ internal class AndroidQWifiListener ( private val wifiManager : WifiManager ) : WifiListener {
2828 @OptIn(ExperimentalCoroutinesApi ::class )
2929 override fun listen (context : Context ): Flow <WifiInfo ?> = callbackFlow {
30- val callback = object : ConnectivityManager .NetworkCallback () {
31- override fun onCapabilitiesChanged (network : Network , networkCapabilities : NetworkCapabilities ) {
32- super .onCapabilitiesChanged(network, networkCapabilities)
30+ // Android 12 requires a new flag to receive SSID data, but flag-based constructor has been introduced only in SDK 31.
31+ val networkCallback = if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .S )
32+ object : ConnectivityManager .NetworkCallback (FLAG_INCLUDE_LOCATION_INFO ) {
33+ override fun onCapabilitiesChanged (network : Network , networkCapabilities : NetworkCapabilities ) {
34+ super .onCapabilitiesChanged(network, networkCapabilities)
3335
34- val wifiInfo = networkCapabilities.transportInfo as WifiInfo
35- @Suppress(" BlockingMethodInNonBlockingContext" )
36- trySendBlocking(wifiInfo)
37- }
38- }
36+ trySendBlocking(networkCapabilities.transportInfo as ? WifiInfo ? )
37+ }
38+ } else
39+ object : ConnectivityManager .NetworkCallback () {
40+ override fun onCapabilitiesChanged (network : Network , networkCapabilities : NetworkCapabilities ) {
41+ super .onCapabilitiesChanged(network, networkCapabilities)
3942
40- val request = NetworkRequest .Builder ()
41- .addTransportType(NetworkCapabilities .TRANSPORT_WIFI )
42- .build()
43+ // There's a weird behavior in SDK 30 where transportInfo is null even when connected to the WiFi.
44+ // Fallback to soon-to-deprecate connectionInfo if we're connected to a WiFi network.
45+ @Suppress(" DEPRECATION" )
46+ val wifiInfo =
47+ (networkCapabilities.transportInfo as ? WifiInfo ? )
48+ ? : if (wifiManager.wifiState == WifiManager .WIFI_STATE_ENABLED ) wifiManager.connectionInfo else null
49+
50+ trySendBlocking(wifiInfo)
51+ }
52+ }
4353
4454 val connectivityManager = context.applicationContext.getSystemService(Context .CONNECTIVITY_SERVICE ) as ConnectivityManager
4555
4656 // Register the callback on network changes.
47- connectivityManager.registerNetworkCallback(request, callback )
57+ connectivityManager.registerDefaultNetworkCallback(networkCallback )
4858
4959 // Wait for flow cancellation, then unregister the callback.
5060 awaitClose {
51- connectivityManager.unregisterNetworkCallback(callback )
61+ connectivityManager.unregisterNetworkCallback(networkCallback )
5262 }
5363 }
5464}
0 commit comments