Observar la conectividad de red con LiveData en Kotlin Android


Observar la conexión de la red de forma permamente usando el componente Livedata de los componentes de arquitectura de Android

Creando ConnectivityLiveData

Archivo original de ConnectivityLiveData le he modificado para que cuando se conecte a una red disponible, detecte si hay conexión saliente a internet usando ping al servidor de google

class ConnectivityLiveData internal constructor(private val connectivityManager: ConnectivityManager) : LiveData<Boolean>() {

    private var lastValue: Boolean? = null

    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
    constructor(application: Application) : this(
        application.getSystemService(Context.CONNECTIVITY_SERVICE)
                as ConnectivityManager
    )

    private val networkCallback = object : ConnectivityManager.NetworkCallback() {
        override fun onAvailable(network: Network?) {
            oneTimeNotify()
        }

        override fun onLost(network: Network?) {
            oneTimeNotify()
        }
    }

    override fun onActive() {
        super.onActive()

        oneTimeNotify()

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            connectivityManager.registerDefaultNetworkCallback(networkCallback)
        } else {
            val builder = NetworkRequest.Builder()
            connectivityManager.registerNetworkCallback(builder.build(), networkCallback)
        }
    }

    override fun onInactive() {
        super.onInactive()
        connectivityManager.unregisterNetworkCallback(networkCallback)
    }

    private fun oneTimeNotify() {
        val newValue = isNetworkAvailable()

        if (lastValue != newValue) {
            postValue(newValue)
            lastValue = newValue
        }
    }


    private fun isNetworkAvailable(): Boolean {
        //val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            val activeNetwork = connectivityManager.activeNetwork ?: return false
            val networkCapabilities =
                connectivityManager.getNetworkCapabilities(activeNetwork) ?: return false
            return when {
                networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
                networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
                networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_BLUETOOTH) -> true
                networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> true
                else -> false
            }
        } else {
            val activeNetwork = connectivityManager.activeNetworkInfo ?: return false
            return activeNetwork.isConnectedOrConnecting
        }
    }
}

He remplazado la función de detección de red ActiveNetwork porque Android Studio me lo marcaba como deprecated.

He añadido prevención de enviar el estado multiples veces, ahora con el método oneTimeNofity() solo se notifica si es diferente al anterior.

Si se desea solo detectar si la conexión es mediante wifi, dentro del métodoisNetworkAvailable remueve los networkCapabilities menos el NetworkCapabilities.TRANSPORT_WIFI

Implementando ConnectivityLiveData

El ViewModel debe extenderse de AndroidViewModel de esa forma se puede obtener el contexto de la aplicación necesario para obtener el ConnectivityManager

class MyViewModel(application: Application) : AndroidViewModel(application) {
    val connectivity: LiveData<Boolean>
 
    init {
        connectivity = ConnectivityLiveData(application)
    }
}

Observando el ConnectivityLiveData

Por último debemos crear el observador del estado de conectividad

private val mViewModel: MyViewModel by lazy {
    ViewModelProvider(this@HomeFragment).get(MyViewModel::class.java)
}
...
mViewModel.connectivity .observe(viewLifecycleOwner, Observer {
     it?.run {
        if (it) {
            Log.d(TAG, "Network ON")
        } else {
            Log.w(TAG, "Network OFF")
        }
    }
 })

Enlaces

Publicado por Codelaby

Mobile DevDesigner

Deja una respuesta

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Salir /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Salir /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Salir /  Cambiar )

Conectando a %s

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

A %d blogueros les gusta esto: