[英]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.