Kotlin Канал asFlow не получает некоторые значения - PullRequest
0 голосов
/ 10 марта 2020

Я хочу обернуть ConnectivityManager.NetworkCallback() обратный вызов в kotlin flow. Но я не всегда получаю результат, предложенный моим каналом. Вот что я делаю

class WifiStateManager @Inject constructor(
    private val connectivityManager: ConnectivityManager,
    private val connectionUtils: ConnectionUtils
) : ConnectionStateManager {

    private var isActive: Boolean = false
    private var name: String? = null
    private var mac: String? = null
    private var commandsChannel: BroadcastChannel<ConnectionState>? = null

    private val networkCallback = object : ConnectivityManager.NetworkCallback() {
        override fun onAvailable(network: Network?) {
            super.onAvailable(network)
            if (network != null) {
                name = connectionUtils.getWifiName()
                mac = connectionUtils.getWifiMac()
                Timber.d("WifiListener Connected ${name}")
                commandsChannel?.offer(ConnectionState.Wifi.Connected(network, name, mac))
            }
        }
        override fun onLost(network: Network?) {
            super.onLost(network)
            if (network != null) {
                Timber.d("WifiListener Disconnected ${name}")
                commandsChannel?.offer(ConnectionState.Wifi.LostConnection(network, name))
            }
        }
    }

    override fun startListening(): Flow<ConnectionState> {
        if (!isActive) {
            commandsChannel = BroadcastChannel(Channel.BUFFERED)
            isActive = true
            val builder = NetworkRequest.Builder()
            connectivityManager.registerNetworkCallback(builder.build(), networkCallback)
        }
        return commandsChannel!!.asFlow()
    }

    override fun stopListening() {
        isActive = false
        connectivityManager.unregisterNetworkCallback(networkCallback)
        commandsChannel?.close()
        commandsChannel = null
    }
}

и вот как я собираю

   private fun listenForWifiStateChanges() = GlobalScope.launch(Dispatchers.Default) {
        wifiStateManager.startListening().collect { wifiState ->
            when (wifiState) {
                is ConnectionState.Wifi.Connected -> {
                    val wifiName = wifiState.name
                    Timber.d("Wifi was connected to ${wifiName}")
                }
                is ConnectionState.Wifi.LostConnection -> {
                    val wifiName = wifiState.wifiName
                     Timber.d("Wifi was disconnected from ${wifiName}")
                }
            }
        }
    }

И вот мой вывод:

WifiListener Connected HomeWifi
Wifi was connected to HomeWifi <- Thats ok
WifiListener Disconnected HomeWifi
Wifi was disconnected from HomeWifi
WifiListener Connected HomeWifi
<--- NOT CALLING
WifiListener Disconnected HomeWifi

Иногда даже первый Wifi was connected to не называется. Это почему? Чего мне не хватает?

...