簡體   English   中英

如何檢查Android中的inter.net連接

[英]How to check internet connection in Android

在我的應用程序中,我想檢查 inte.net 連接,為此我寫了下面的代碼。
但是在運行應用程序並斷開 inte.net 之前,不會調用已檢查的 inte.net 代碼!
就在 inte.net 連接已連接並使用已連接的 inte.net 運行應用程序時,然后斷開 inte.net 顯示 inte.net 已連接或斷開連接!

互聯網連接 class :

class NetworkConnectivity @Inject constructor(private val manager: ConnectivityManager, private val request: NetworkRequest) : ConnectivityStatus {
    override fun observe(): Flow<Boolean> {
        return callbackFlow {
            val callback = object : ConnectivityManager.NetworkCallback() {
                override fun onAvailable(network: Network) {
                    super.onAvailable(network)
                    launch { send(true) }
                }

                override fun onLost(network: Network) {
                    super.onLost(network)
                    launch { send(false) }
                }
            }

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                manager.registerDefaultNetworkCallback(callback)
            } else {
                manager.registerNetworkCallback(request, callback)
            }
            awaitClose {
                manager.unregisterNetworkCallback(callback)
            }
        }
    }
}

查看模型 class:

@HiltViewModel
class DetailViewModel @Inject constructor(private val repository: MainRepository) : ViewModel() {
    @Inject
    lateinit var networkConnectivity: NetworkConnectivity    

    val detailData = MutableLiveData<NetworkRequest<ResponseDetailPage>>()
    fun callDetailApi(id: Int, apiKey: String) = viewModelScope.launch {
        Log.e("DetailLog","ViewModel 1")
        networkConnectivity.observe().collect {
            if (it) {
                Log.e("DetailLog","ViewModel 2")
                detailData.value = NetworkRequest.Loading()
                //Response
                val response = repository.remote.recipeInformation(id, apiKey)
                detailData.value = NetworkResponse(response).generalNetworkResponse()
            } else {
                Log.e("DetailLog","ViewModel 3")
                detailData.value = NetworkRequest.Error("No internet connection")
            }
        }
    }
}

運行應用程序后(當 inte.net 斷開連接時)只需在logcat中顯示ViewModel 1登錄!

為什么在以斷開連接模式啟動應用程序時不檢查 inte.net?

我正在使用這個function檢查 inte.net 連接:

fun isInternetAvailable(context: Context): Boolean {
        var result = false
        val connectivityManager =
                context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            val networkCapabilities = connectivityManager.activeNetwork ?: return false
            val actNw =
                    connectivityManager.getNetworkCapabilities(networkCapabilities) ?: return false
            result = when {
                actNw.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
                actNw.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
                actNw.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> true
                else -> false
            }
        } else {
            connectivityManager.run {
                connectivityManager.activeNetworkInfo?.run {
                    result = when (type) {
                        ConnectivityManager.TYPE_WIFI -> true
                        ConnectivityManager.TYPE_MOBILE -> true
                        ConnectivityManager.TYPE_ETHERNET -> true
                        else -> false
                    }

                }
            }
        }
        return result
    }

如果您以 SDK23+ 為目標,則可以刪除構建版本檢查。

這是我在我的視圖模型中調用這個function的方式:

private val _internetIsAvailable = MutableLiveData<Boolean?>()
    val extInternetAvailable: LiveData<Boolean?> get() = _internetIsAvailable
    private val _loadStatus = MutableLiveData<LoadStatus>()
    val extLoadStatus: LiveData<LoadStatus> get() = _loadStatus

    init {
        // runs every time VM is created (not view created)
        viewModelScope.launch {
            _loadStatus.value = LoadStatus.LOADING
            _internetIsAvailable.value = NetworkChecker(app).isInternetAvailable()
            _loadStatus.value = LoadStatus.DONE
        }
    }

片段中

private fun observeInternetAvailability() {
        mainVM.extInternetAvailable.observe(this) { intAvailable ->
            Logger.d("Internet is $intAvailable")
            if (intAvailable == false) {
                ToastUtils.updateWarning(this, getString(R.string.no_internet))
                showLoading(true)
            }
        }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM