In my application I want check inte.net connection and for this I write below codes.
But when before run application and disconnect inte.net, not call checked inte.net code!
Just when inte.net connection is connected and run application with connected inte.net then disconnect inte.net show inte.net is connect or disconnect!
Inte.net connection 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)
}
}
}
}
ViewModel 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")
}
}
}
}
After run application (when inte.net is disconnected) just show ViewModel 1 log in logcat
!
Why not checked inte.net when start application with disconnected mode?
I'm using this function to check for inte.net connectivity:
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
}
If you target SDK23+, you can remove build version check.
Here's how I call this function in my viewmodel :
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
}
}
In fragments :
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)
}
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.