Skip to content

Instantly share code, notes, and snippets.

@Morteza-QN
Last active January 13, 2022 07:08
Show Gist options
  • Save Morteza-QN/8580918048a7035012dc528a3e5face9 to your computer and use it in GitHub Desktop.
Save Morteza-QN/8580918048a7035012dc528a3e5face9 to your computer and use it in GitHub Desktop.
check connectivity network by liveData
import timber.log.Timber
import java.net.InetSocketAddress
import java.net.Socket
object InternetAvailability {
val isAvailable: Boolean
get() {
return try {
val socket = Socket()
socket.connect(InetSocketAddress("8.8.8.8", 53))
socket.close()
Timber.i("internet available")
true
} catch (e: Exception) {
e.printStackTrace()
Timber.e("internet unavailable")
false
}
}
}
sealed class NetworkStatus {
object Available : NetworkStatus()
object Unavailable : NetworkStatus()
}
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.net.*
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.lifecycle.LiveData
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import timber.log.Timber
class NetworkStatusHelper(private val context: Context) : LiveData<NetworkStatus>() {
private val validNetworkConnections: ArrayList<Network> = ArrayList()
private var connectivityManager: ConnectivityManager =
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
private lateinit var connectivityManagerCallback: ConnectivityManager.NetworkCallback
private val networkReceiver = object : BroadcastReceiver() {
override fun onReceive(p0: Context?, p1: Intent?) {
updateConnection()
}
}
private fun updateConnection() {
val activeNetwork: NetworkInfo? = connectivityManager.activeNetworkInfo
CoroutineScope(Dispatchers.IO).launch {
if (activeNetwork?.isConnected == true) {
if (InternetAvailability.isAvailable)
withContext(Dispatchers.Main) { postValue(NetworkStatus.Available) }
else withContext(Dispatchers.Main) { postValue(NetworkStatus.Unavailable) }
} else withContext(Dispatchers.Main) { postValue(NetworkStatus.Unavailable) }
}
if (activeNetwork?.isConnected == true)
postValue(NetworkStatus.Available)
else
postValue(NetworkStatus.Unavailable)
}
private fun announceStatus() {
if (validNetworkConnections.isNotEmpty()) {
postValue(NetworkStatus.Available)
} else {
postValue(NetworkStatus.Unavailable)
}
}
private fun determineInternetAccess(network: Network) {
CoroutineScope(Dispatchers.IO).launch {
if (InternetAvailability.isAvailable) {
withContext(Dispatchers.Main) {
validNetworkConnections.add(network)
announceStatus()
}
}
}
}
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
fun getConnectivityManagerCallback() =
object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
super.onAvailable(network)
val networkCapability = connectivityManager.getNetworkCapabilities(network)
val hasNetworkConnection =
networkCapability?.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) ?: false
if (hasNetworkConnection) {
Timber.i("network connection available")
determineInternetAccess(network)
} else Timber.e("network connection unavailable")
}
override fun onLost(network: Network) {
super.onLost(network)
Timber.e("network connection unavailable")
validNetworkConnections.remove(network)
announceStatus()
}
override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) {
super.onCapabilitiesChanged(network, networkCapabilities)
if (networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
Timber.i("network connection available")
determineInternetAccess(network)
} else {
Timber.e("network connection unavailable")
validNetworkConnections.remove(network)
}
announceStatus()
}
}
override fun onActive() {
super.onActive()
when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.N -> {
connectivityManagerCallback = getConnectivityManagerCallback()
connectivityManager.registerDefaultNetworkCallback(connectivityManagerCallback)
}
Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP -> {
connectivityManagerCallback = getConnectivityManagerCallback()
val networkRequest = NetworkRequest.Builder()
// .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
// .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
// .addTransportType(NetworkCapabilities.TRANSPORT_ETHERNET)
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.build()
connectivityManager.registerNetworkCallback(networkRequest, connectivityManagerCallback)
}
else -> {
updateConnection()
context.registerReceiver(networkReceiver, IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION))
}
}
}
override fun onInactive() {
super.onInactive()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
connectivityManager.unregisterNetworkCallback(connectivityManagerCallback)
} else {
context.unregisterReceiver(networkReceiver)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment