From very small and basic android projects to complex and big projects, It is very common practice to connect mobile applications to Internet connection to get all customer insights with all other features and also to inform users in real time whether Internet connection is available or not. Here in this article we will guide you how to achieve this using StateFlow.
Why StateFlow?
StateFlow is FlowAPI which enables flow to emit data to its consumers. StateFlow is an observable flow that emits new and changed state updates to its collectors.
For a start let’s create ConnectivityObserver interface
This interface contains a Status enum class with different connectivity values and an observer function that returns the current Internet Connection status flow.
interface ConnectivityObserver {
fun observe(): Flow<Status>
enum class Status {
Available, Unavailable, Losing, Lost
}
}
Now let’s Create NetworkConnectivityObserver class.
Here, We have built flow with a callback builder function that takes lambda as a parameter, and Flow will emit the data using send function. On the connectivity manager, we will receive four types of callbacks based on Network connectivity. In this project, we will use ConnectivityManager system service to get information about network connectivity.
class NetworkConnectivityObserver(
private val context: Context
) : ConnectivityObserver {
private val connectivityManager =
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
@RequiresApi(Build.VERSION_CODES.N)
override fun observe(): Flow<ConnectivityObserver.Status> {
return callbackFlow {
val callback = object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
super.onAvailable(network)
launch { send(ConnectivityObserver.Status.Available) }
}
override fun onLosing(network: Network, maxMsToLive: Int) {
super.onLosing(network, maxMsToLive)
launch { send(ConnectivityObserver.Status.Losing) }
}
override fun onLost(network: Network) {
super.onLost(network)
launch { send(ConnectivityObserver.Status.Lost) }
}
override fun onUnavailable() {
super.onUnavailable()
launch { send(ConnectivityObserver.Status.Unavailable) }
}
}
connectivityManager.registerDefaultNetworkCallback(callback)
awaitClose {
connectivityManager.unregisterNetworkCallback(callback)
}
}.distinctUntilChanged()
}
}
Now let’s add NetworkConnectivityObserver to our class
It is straightforward now. Create an instance of NetworkConnectivityObserver let’s call it connectivityObserver, which will observe the state of status flow and collect the changed flow.
private var connectivityObserver: ConnectivityObserver = NetworkConnectivityObserver(applicationContext)
lifecycleScope.launch {
connectivityObserver.observe().collect {
showToast(it.toString())
}
}
Create this instance of NetworkConnectivityObserver in an activity that requires an Internet Connection and run the application. It will work as expected.