@@ -7,16 +7,12 @@ import android.net.wifi.WifiManager
7
7
import android.os.Build
8
8
import androidx.core.content.ContextCompat
9
9
import androidx.core.content.PermissionChecker.PERMISSION_GRANTED
10
- import androidx.lifecycle.LiveData
11
- import kotlinx.coroutines.*
12
- import net.kuama.wifiMonitor.data.WiFiInfo
13
- import net.kuama.wifiMonitor.data.WifiNetworkBand
14
- import net.kuama.wifiMonitor.data.WifiState
10
+ import kotlinx.coroutines.Dispatchers
11
+ import kotlinx.coroutines.withContext
12
+ import net.kuama.wifiMonitor.data.WifiStatus
15
13
import net.kuama.wifiMonitor.implementation.AndroidQWifiListener
16
14
import net.kuama.wifiMonitor.implementation.BeforeAndroidQWifiListener
17
15
18
- private fun noop () {}
19
-
20
16
class WifiMonitor (context : Context ) {
21
17
22
18
private val listener = if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .Q ) {
@@ -26,94 +22,75 @@ class WifiMonitor(context: Context) {
26
22
BeforeAndroidQWifiListener (context)
27
23
}
28
24
29
- private val scope = CoroutineScope (SupervisorJob () + Dispatchers .Default )
30
-
31
25
private val wifiManager: WifiManager =
32
26
context.applicationContext.getSystemService(Context .WIFI_SERVICE ) as WifiManager
33
27
34
- fun stop () = listener.stop()
35
-
36
- fun start (onChange : () -> Unit ) = scope.launch { listener.start(onChange) }
37
-
38
- val state: Int
39
- get() = wifiManager.wifiState
40
-
41
- val connectionInfo: WifiInfo
42
- get() = wifiManager.connectionInfo
43
-
44
- val isFineLocationAccessGranted = ContextCompat .checkSelfPermission(
45
- context,
46
- Manifest .permission.ACCESS_FINE_LOCATION
47
- ) == PERMISSION_GRANTED
48
- }
49
-
50
- class WifiLiveData constructor(private val monitor : WifiMonitor ) :
51
- LiveData <WiFiInfo >() {
52
-
53
- private var startJob: Job ? = null
54
-
55
- override fun onActive () {
56
- super .onActive()
57
- startJob = monitor.start(::onWifiChange)
58
- }
59
-
60
- override fun onInactive () {
61
- super .onInactive()
62
- if (startJob?.isActive == true ) {
63
- startJob?.cancel()
64
- }
65
- monitor.stop()
66
- }
67
-
68
28
/* *
69
- * Will check the current wifi state and propagate different infos
70
- * based on it.
29
+ * Whether we received at least a Wi-Fi change status. When false, we cannot say we are connected
71
30
*/
72
- private fun onWifiChange () {
73
- when (monitor.state) {
74
- WifiManager .WIFI_STATE_DISABLED , WifiManager .WIFI_STATE_DISABLING -> onWifiDisabled()
75
- WifiManager .WIFI_STATE_ENABLED -> onWifiEnabled(monitor.connectionInfo)
76
- WifiManager .WIFI_STATE_ENABLING -> noop()
77
- else -> onCouldNotGetWifiState()
78
- }
79
- }
31
+ private var didReceiveChange = false
80
32
81
33
/* *
82
- * Propagates a [WifiState.DISCONNECTED] state
34
+ * Stop listening to Wi-Fi changes
83
35
*/
84
- private fun onWifiDisabled () = postValue( WiFiInfo ( WifiState . DISCONNECTED ) )
36
+ fun stop () = listener.stop( )
85
37
86
38
/* *
87
- * Propagates a [WifiState.CONNECTED] state, and the
88
- * current wi-fi ssid (if android.permission.ACCESS_FINE_LOCATION was granted,
89
- * <unknown-ssid> otherwise)
39
+ * Triggers the on change callback whenever the Wi-Fi changes its status
90
40
*/
91
- private fun onWifiEnabled (connectionInfo : WifiInfo ) {
41
+ suspend fun observe (onChange : (WifiStatus ) -> Unit ) =
42
+ withContext(Dispatchers .Default ) {
43
+ listener.start {
44
+ didReceiveChange = true
45
+ onChange(info)
46
+ }
47
+ }
48
+
49
+ private val state: Int
50
+ get() = wifiManager.wifiState
51
+
52
+ private val connectionInfo: WifiInfo
53
+ get() = wifiManager.connectionInfo
92
54
93
- val band = if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .LOLLIPOP ) {
55
+ private val band: WifiStatus .NetworkBand
56
+ get() = if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .LOLLIPOP ) {
94
57
if (connectionInfo.frequency > 3000 ) {
95
- WifiNetworkBand .WIFI_5_GHZ
58
+ WifiStatus . NetworkBand .WIFI_5_GHZ
96
59
} else {
97
- WifiNetworkBand .WIFI_2_4_GHZ
60
+ WifiStatus . NetworkBand .WIFI_2_4_GHZ
98
61
}
99
62
} else {
100
- WifiNetworkBand .UNKNOWN
63
+ WifiStatus . NetworkBand .UNKNOWN
101
64
}
102
65
103
- postValue(
104
- WiFiInfo (
105
- state = if (monitor.isFineLocationAccessGranted) WifiState .CONNECTED else WifiState .CONNECTED_MISSING_FINE_LOCATION_PERMISSION ,
106
- ssid = connectionInfo.ssid,
107
- bssid = connectionInfo.bssid,
108
- band = band,
109
- rssi = connectionInfo.rssi
110
- )
111
- )
112
- }
66
+ /* *
67
+ * Holds the current information on the Wi-Fi connection.
68
+ */
69
+ val info: WifiStatus
70
+ get() = if (didReceiveChange) {
71
+ when (state) {
72
+ WifiManager .WIFI_STATE_DISABLED , WifiManager .WIFI_STATE_DISABLING -> WifiStatus (
73
+ WifiStatus .State .DISCONNECTED
74
+ )
75
+ WifiManager .WIFI_STATE_ENABLED -> WifiStatus (
76
+ state = if (isFineLocationAccessGranted) WifiStatus .State .CONNECTED else WifiStatus .State .CONNECTED_MISSING_FINE_LOCATION_PERMISSION ,
77
+ ssid = connectionInfo.ssid,
78
+ bssid = connectionInfo.bssid,
79
+ band = band,
80
+ rssi = connectionInfo.rssi
81
+ )
82
+ WifiManager .WIFI_STATE_ENABLING -> WifiStatus (WifiStatus .State .ENABLING )
83
+ else -> WifiStatus (WifiStatus .State .UNKNOWN )
84
+ }
85
+ } else {
86
+ WifiStatus (WifiStatus .State .UNKNOWN )
87
+ }
113
88
114
89
/* *
115
- * Propagates a [WifiState.UNKNOWN] state.
116
- * Typically it's the first value that gets emitted to the subscribers
90
+ * True if the user granted access to [Manifest.permission.ACCESS_FINE_LOCATION]
117
91
*/
118
- private fun onCouldNotGetWifiState () = postValue(WiFiInfo (WifiState .UNKNOWN ))
92
+ val isFineLocationAccessGranted: Boolean = ContextCompat .checkSelfPermission(
93
+ context,
94
+ Manifest .permission.ACCESS_FINE_LOCATION
95
+ ) == PERMISSION_GRANTED
119
96
}
0 commit comments