如何在 Kotlin 协程中从布尔值返回/转换 Flow<Boolean>?

BRD*_*oid 0 android flow kotlin kotlin-coroutines kotlin-coroutines-flow

我有一个 Android 库,我在其中监听网络变化,我想做的是,使用 Flow/launch of coroutines 观察这些变化

这是我的 NetworkReceiver,它让我知道连接何时发生变化

我采用了一个变量isNetworkConnectionActive,该变量init在库中设置为 false,并根据网络更改在以下函数中设置为 true false

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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

OfflineDataLibrary 具有 isNetworkConnectionActive

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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我想听听isNetworkConnectionActive变量发生的变化Flow **** 这里我有一个类型不匹配,我想返回布尔值但我返回布尔值。***

  fun getNetworkAvailability(): Flow<Boolean> {

        return OfflineDataLibrary.isNetworkConnectionActive
    }
Run Code Online (Sandbox Code Playgroud)

我可以访问上述功能并听取这样的变化

  fun getIsNetworkAvailable() {
        launch {
        OfflineDatabaseManager.getInstance(app.applicationContext).getNetworkAvailability().collect {
                //DO something
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

我怎样才能转换BooleanFlow<Boolean>

如果您认为还有其他方式可以订阅网络上发生的变化,请告诉我。

感谢您的帮助和建议。电阻

Gle*_*val 5

随着StateFlow你没有使用LiveDataConflatedChannel和你甚至不用到转换ChannelFlow

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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

你所要做的就是从课堂外收集它的价值。请记住,它已合并,因此在其值更改之前不会通知观察者:

myConnectionChangeReceiver.networkConnectionActivated
    .collect {  isNetworkConnectionActive ->
        //Do something here
    }
Run Code Online (Sandbox Code Playgroud)

不要忘记在需要时通过取消它们正在运行的所有协程来停止所有观察者。

您可以在此处找到StateFlow官方文档。