Skip to content

Commit a49ee90

Browse files
committed
one shot wi-fi status
1 parent 73da821 commit a49ee90

File tree

11 files changed

+174
-143
lines changed

11 files changed

+174
-143
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
## Unreleased
22

3+
# Version 1.1.1
4+
> 2021-06-10
5+
- Expose current `WiFiStatus`
6+
37
# Version 1.1.0
48
> 2021-06-09
59
- Expose `WifiLiveData`

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,19 @@ class MainActivity : AppCompatActivity() {
2020
println(it.bssid)
2121
println(it.state.name)
2222
}
23+
24+
// Or more simply
25+
val monitor = WifiMonitor(context)
26+
27+
// currently available information
28+
monitor.info
29+
30+
// observe changes
31+
lifecycleScope.launchWhenStarted {
32+
monitor.observe { freshInfo ->
33+
34+
}
35+
}
2336
}
2437
}
2538

gradle.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@ org.gradle.jvmargs=-Xmx1536m
22
android.useAndroidX=true
33
android.enableJetifier=true
44
kotlin.code.style=official
5-
version_code=7
6-
version_name=1.1.0
5+
version_code=8
6+
version_name=1.1.1

src/main/java/net/kuama/wifiMonitor/WifiListener.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package net.kuama.wifiMonitor
22

3+
/**
4+
* Allows to trigger a callback whenever Wi-Fi changes its status
5+
*/
36
interface WifiListener {
47
fun stop()
58

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package net.kuama.wifiMonitor
2+
3+
import androidx.lifecycle.LiveData
4+
import kotlinx.coroutines.*
5+
import net.kuama.wifiMonitor.data.WifiStatus
6+
7+
class WifiLiveData constructor(private val monitor: WifiMonitor) :
8+
LiveData<WifiStatus>() {
9+
10+
private var startJob: Job? = null
11+
12+
override fun onActive() {
13+
super.onActive()
14+
startJob = CoroutineScope(SupervisorJob() + Dispatchers.Default).launch {
15+
monitor.observe(::postValue)
16+
}
17+
}
18+
19+
override fun onInactive() {
20+
super.onInactive()
21+
if (startJob?.isActive == true) {
22+
startJob?.cancel()
23+
}
24+
monitor.stop()
25+
}
26+
}

src/main/java/net/kuama/wifiMonitor/WifiMonitor.kt

Lines changed: 53 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,12 @@ import android.net.wifi.WifiManager
77
import android.os.Build
88
import androidx.core.content.ContextCompat
99
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
1513
import net.kuama.wifiMonitor.implementation.AndroidQWifiListener
1614
import net.kuama.wifiMonitor.implementation.BeforeAndroidQWifiListener
1715

18-
private fun noop() {}
19-
2016
class WifiMonitor(context: Context) {
2117

2218
private val listener = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
@@ -26,94 +22,75 @@ class WifiMonitor(context: Context) {
2622
BeforeAndroidQWifiListener(context)
2723
}
2824

29-
private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Default)
30-
3125
private val wifiManager: WifiManager =
3226
context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
3327

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-
6828
/**
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
7130
*/
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
8032

8133
/**
82-
* Propagates a [WifiState.DISCONNECTED] state
34+
* Stop listening to Wi-Fi changes
8335
*/
84-
private fun onWifiDisabled() = postValue(WiFiInfo(WifiState.DISCONNECTED))
36+
fun stop() = listener.stop()
8537

8638
/**
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
9040
*/
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
9254

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) {
9457
if (connectionInfo.frequency > 3000) {
95-
WifiNetworkBand.WIFI_5_GHZ
58+
WifiStatus.NetworkBand.WIFI_5_GHZ
9659
} else {
97-
WifiNetworkBand.WIFI_2_4_GHZ
60+
WifiStatus.NetworkBand.WIFI_2_4_GHZ
9861
}
9962
} else {
100-
WifiNetworkBand.UNKNOWN
63+
WifiStatus.NetworkBand.UNKNOWN
10164
}
10265

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+
}
11388

11489
/**
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]
11791
*/
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
11996
}

src/main/java/net/kuama/wifiMonitor/data/WiFiInfo.kt

Lines changed: 0 additions & 28 deletions
This file was deleted.

src/main/java/net/kuama/wifiMonitor/data/WifiNetworkBand.kt

Lines changed: 0 additions & 5 deletions
This file was deleted.

src/main/java/net/kuama/wifiMonitor/data/WifiState.kt

Lines changed: 0 additions & 27 deletions
This file was deleted.
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package net.kuama.wifiMonitor.data
2+
3+
import android.Manifest
4+
import net.kuama.wifiMonitor.WifiMonitor
5+
6+
/**
7+
* Collects a set of useful properties about the WiFi
8+
*/
9+
class WifiStatus(
10+
/**
11+
* Connection state
12+
*/
13+
val state: State,
14+
15+
/**
16+
* Name of the current access point.
17+
* Can be "<unknown-ssid>" when [Manifest.permission.ACCESS_FINE_LOCATION] has not been granted
18+
*/
19+
val ssid: String? = null,
20+
21+
/**
22+
* Basic service set identifier (BSSID) of the current access point.
23+
*/
24+
val bssid: String? = null,
25+
26+
/**
27+
* 2.4 or 5 ghz (or unknown) of the current access point.
28+
*/
29+
val band: NetworkBand = NetworkBand.UNKNOWN,
30+
31+
/**
32+
* Signal strength indicator of the current 802.11 network, in dBm.
33+
*/
34+
val rssi: Int? = null
35+
) {
36+
enum class State {
37+
/**
38+
* Wi-Fi is currently connected and we should be able to read all of the information we need
39+
*/
40+
CONNECTED,
41+
42+
/**
43+
* If Wi-Fi is connected but you didn't ask your user for fine location access permission
44+
* you'll get this state with the "<unknown-ssid>" string inside a [WifiStatus] object
45+
*/
46+
CONNECTED_MISSING_FINE_LOCATION_PERMISSION,
47+
48+
/**
49+
* Wi-Fi is currently being disabled or Wi-Fi is disabled
50+
*/
51+
DISCONNECTED,
52+
53+
/**
54+
* Wi-Fi is currently being enabled. The state will change to {@link #WIFI_STATE_ENABLED} if
55+
* it finishes successfully.
56+
*/
57+
ENABLING,
58+
59+
/**
60+
* Either there was an error trying to read Wi-Fi state or nobody called [WifiMonitor.observe]
61+
*/
62+
UNKNOWN
63+
}
64+
65+
enum class NetworkBand {
66+
UNKNOWN, WIFI_2_4_GHZ, WIFI_5_GHZ
67+
}
68+
}

0 commit comments

Comments
 (0)