Issue
I have an Android library in which I am listening to network changes, what I want to do is, observe those changes using Flow/launch of coroutines
This is my NetworkReceiver, which lets me know when there are changes in the connection
I have taken a variable isNetworkConnectionActive
which is set to false on the init
of the library and is set true false in the below function based on the network changes
class ConnectionChangeReceiver: BroadcastReceiver() {
override fun onReceive(context: Context?, p1: Intent?) {
if(isNetworkConnectionActive(context)) {
OfflineDataLibrary.isNetworkConnectionActive = true
Toast.makeText(context, "isNetworkConnectionActive - YES", Toast.LENGTH_LONG).show()
} else {
OfflineDataLibrary.isNetworkConnectionActive = false
Toast.makeText(context, "isNetworkConnectionActive - NO", Toast.LENGTH_LONG).show()
}
}
fun isNetworkConnectionActive(context: Context?): Boolean {
val connectivityManager: ConnectivityManager = context?.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
var isConnectionActive = false
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val nw = connectivityManager.activeNetwork ?: return false
val actNw = connectivityManager.getNetworkCapabilities(nw) ?: return false
return when {
actNw.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
actNw.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
else -> false
}
} else {
val nwInfo = connectivityManager.activeNetworkInfo ?: return false
return nwInfo.isConnected
}
}
}
OfflineDataLibrary which has isNetworkConnectionActive
object OfflineDataLibrary {
lateinit var context: Context
var isNetworkConnectionActive: Boolean = false
fun init(ctx: Context) {
context = ctx.applicationContext
val offlineDataChangeListener = OfflineDataChangeListener()
offlineDataChangeListener.observeOfflineDataChanges()
}
}
Now I want to listen to changes happening on isNetworkConnectionActive
variable using a Flow
*HERE I HAVE A TYPE MISMATCH, I WANT TO RETURN FLOW OF BOOLEAN BUT BUT I AM RETURNING BOOLEAN.
fun getNetworkAvailability(): Flow<Boolean> {
return OfflineDataLibrary.isNetworkConnectionActive
}
I can access the above function and listen to changes like this
fun getIsNetworkAvailable() {
launch {
OfflineDatabaseManager.getInstance(app.applicationContext).getNetworkAvailability().collect {
//DO something
}
}
}
How can I convert Boolean
to Flow<Boolean>
?
If you think there can be any other way to subscribe to changes happening on the network, please let me know.
Solution
With StateFlow
you don't have to use a LiveData
or a ConflatedChannel
and you don't even have to convert a Channel
into a Flow
:
class ConnectionChangeReceiver: BroadcastReceiver() {
private val _networkConnectionActivated = MutableStateFlow(false) //An initial value is required
val networkConnectionActivated: StateFlow<Boolean>
get() = _networkConnectionActivated
override fun onReceive(context: Context?, p1: Intent?) {
_networkConnectionActivated.value = isNetworkConnectionActive(context)
}
fun isNetworkConnectionActive(context: Context?): Boolean {
val connectivityManager: ConnectivityManager = context?.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
var isConnectionActive = false
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val nw = connectivityManager.activeNetwork ?: return false
val actNw = connectivityManager.getNetworkCapabilities(nw) ?: return false
return when {
actNw.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
actNw.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
else -> false
}
} else {
val nwInfo = connectivityManager.activeNetworkInfo ?: return false
return nwInfo.isConnected
}
}
}
All you have to do is collect its value from outside the class. Remember it's conflated so observers won't be notified until its value changes:
myConnectionChangeReceiver.networkConnectionActivated
.collect { isNetworkConnectionActive ->
//Do something here
}
Don't forget to stop all the observers when required by cancelling all the coroutines where they're running on.
You can find StateFlow
official documentation here.
Answered By - Glenn Sandoval
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.