Observar la conectividad de Internet con LiveData en Kotlin Android


Si se requiere detectar la conexión a internet permamente y así tener un control cuando se pierde la conexión y informar el usuario, usando los componentes de arquitectura de Android combinando viewModel con LiveData

Creando ConnectivityOnlineLiveData

Usando la nuevas API ConnectivityManager.NetworkCallback() para obtener la conectividad en combinación con LiveData (de Android Architecture Components) podemos crear una maravillosa clase observable para proporcionar esta devolución de llamada de cambio de conectividad.

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

import android.Manifest
import android.app.Application
import android.content.Context
import android.net.*
import android.os.Build
import androidx.annotation.RequiresPermission
import androidx.lifecycle.LiveData

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

    private var lastValue: Boolean? = null

    @RequiresPermission(allOf = [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()
                .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
                .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
                .addTransportType(NetworkCapabilities.TRANSPORT_BLUETOOTH)
                .addTransportType(NetworkCapabilities.TRANSPORT_ETHERNET)
            connectivityManager.registerNetworkCallback(builder.build(), networkCallback)
        }
    }

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

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

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

    private fun isNetworkIsAvailable(): Boolean {
        val activeNetwork: NetworkInfo? = connectivityManager.activeNetworkInfo
        return activeNetwork?.isConnected == true
    }

    @RequiresPermission(android.Manifest.permission.INTERNET)
    private fun isInternetOn(): Boolean {
        if (isNetworkIsAvailable()) {
            try {
                val p = Runtime.getRuntime().exec("ping -c 1 www.google.com")
                val value = p.waitFor()
                return value == 0

            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
        return false
    }

}

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

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 = ConnectivityOnlineLiveData(application)
    }
}

Observando el ConnectivityOneLiveData

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, "Internet ON")
        } else {
            Log.w(TAG, "Internet OFF")
        }
    }
 })

Enlaces

Publicado por Codelaby

Mobile DevDesigner

2 comentarios sobre “Observar la conectividad de Internet con LiveData en Kotlin Android

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: