released not net manager found for example connectivitymanager connectivity_change connectivity_action conn callbackhandler android

android - not - constants connectivity_action



ConnectivityManager.CONNECTIVITY_ACTION en desuso (8)

Actualizaré Sayem''s respuesta Sayem''s para solucionar los problemas de pelusa que me muestra.

class ConnectionLiveData(val context: Context) : LiveData<Boolean>() { private var connectivityManager: ConnectivityManager = context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager private lateinit var connectivityManagerCallback: ConnectivityManager.NetworkCallback override fun onActive() { super.onActive() updateConnection() when { Build.VERSION.SDK_INT >= Build.VERSION_CODES.N -> connectivityManager.registerDefaultNetworkCallback(getConnectivityManagerCallback()) Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP -> lollipopNetworkAvailableRequest() else -> { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { context.registerReceiver(networkReceiver, IntentFilter("android.net.conn.CONNECTIVITY_CHANGE")) // android.net.ConnectivityManager.CONNECTIVITY_ACTION } } } } override fun onInactive() { super.onInactive() if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { connectivityManager.unregisterNetworkCallback(connectivityManagerCallback) } else { context.unregisterReceiver(networkReceiver) } } @TargetApi(Build.VERSION_CODES.LOLLIPOP) private fun lollipopNetworkAvailableRequest() { val builder = NetworkRequest.Builder() .addTransportType(android.net.NetworkCapabilities.TRANSPORT_CELLULAR) .addTransportType(android.net.NetworkCapabilities.TRANSPORT_WIFI) connectivityManager.registerNetworkCallback(builder.build(), getConnectivityManagerCallback()) } private fun getConnectivityManagerCallback(): ConnectivityManager.NetworkCallback { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { connectivityManagerCallback = object : ConnectivityManager.NetworkCallback() { override fun onAvailable(network: Network?) { postValue(true) } override fun onLost(network: Network?) { postValue(false) } } return connectivityManagerCallback } else { throw IllegalAccessError("Should not happened") } } private val networkReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { updateConnection() } } private fun updateConnection() { val activeNetwork: NetworkInfo? = connectivityManager.activeNetworkInfo postValue(activeNetwork?.isConnected == true) } }

Y el mismo uso:

val connectionLiveData = ConnectionLiveData(context) connectionLiveData.observe(this, Observer { isConnected -> isConnected?.let { // do job } })

Por cierto, gracias sayem por tu solución.

En Android N, se menciona en el sitio web oficial que "Las aplicaciones dirigidas a Android N no reciben transmisiones de CONNECTIVITY_ACTION". Y también se menciona que JobScheduler se puede utilizar como alternativa. Pero JobScheduler no proporciona exactamente el mismo comportamiento que la transmisión CONNECTIVITY_ACTION .

En mi aplicación de Android, estaba usando esta transmisión para conocer el estado de la red del dispositivo. Quería saber si este estado se estaba CONNECTING o CONNECTED con la ayuda de la transmisión CONNECTIVITY_ACTION y era el más adecuado para mi requerimiento.

Ahora que está en desuso, ¿alguien puede sugerirme el enfoque alternativo para obtener el estado actual de la red?


Compruebe primero la respuesta de @Amokrane Chentir para obtener compatibilidad con Android N.

Para aquellos que quieran apoyar en todos los niveles de API y observarlo en la interfaz de usuario, verifique el siguiente código.

LiveData de NetworkConnection:

class ConnectionLiveData(val context: Context) : LiveData<Boolean>(){ var intentFilter = IntentFilter(CONNECTIVITY_ACTION) private var connectivityManager = context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager private lateinit var networkCallback : NetworkCallback init { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { networkCallback = NetworkCallback(this) } } override fun onActive() { super.onActive() updateConnection() when { Build.VERSION.SDK_INT >= Build.VERSION_CODES.N -> connectivityManager.registerDefaultNetworkCallback(networkCallback) Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP -> { val builder = NetworkRequest.Builder().addTransportType(TRANSPORT_CELLULAR).addTransportType(TRANSPORT_WIFI) connectivityManager.registerNetworkCallback(builder.build(), networkCallback) } else -> { context.registerReceiver(networkReceiver, intentFilter) } } } override fun onInactive() { super.onInactive() if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { connectivityManager.unregisterNetworkCallback(networkCallback) } else{ context.unregisterReceiver(networkReceiver) } } private val networkReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { updateConnection() } } fun updateConnection() { val activeNetwork: NetworkInfo? = connectivityManager.activeNetworkInfo postValue(activeNetwork?.isConnectedOrConnecting == true) } @RequiresApi(Build.VERSION_CODES.LOLLIPOP) class NetworkCallback(val liveData : ConnectionLiveData) : ConnectivityManager.NetworkCallback() { override fun onAvailable(network: Network?) { liveData.postValue(true) } override fun onLost(network: Network?) { liveData.postValue(false) } } }

observar en UI (Actividad / Fragmento):

val connectionLiveData = ConnectionLiveData(context) connectionLiveData.observe(this, Observer { // do whatever you want with network connectivity change })


Escribí una implementación de Kotlin que se basa en la respuesta de Sayam pero sin LiveData . Decidí invocar el último método de API (en este momento) ( ConnectivityManager#registerDefaultNetworkCallback ) que apunta a Android Nougat.

/** * Observes network connectivity by consulting the [ConnectivityManager]. * Observing can run infinitely or automatically be stopped after the first response is received. */ class ConnectivityObserver @JvmOverloads constructor( val context: Context, val onConnectionAvailable: () -> Unit, val onConnectionLost: () -> Unit = {}, val shouldStopAfterFirstResponse: Boolean = false ) { private val connectivityManager get() = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager @Suppress("DEPRECATION") private val intentFilter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION) private val broadCastReceiver = object : BroadcastReceiver() { @Suppress("DEPRECATION") override fun onReceive(context: Context?, intent: Intent?) { if (ConnectivityManager.CONNECTIVITY_ACTION != intent?.action) { return } val networkInfo = connectivityManager.activeNetworkInfo if (networkInfo != null && networkInfo.isConnectedOrConnecting) { onConnectionAvailable.invoke() } else { onConnectionLost.invoke() } if (shouldStopAfterFirstResponse) { stop() } } } private lateinit var networkCallback: ConnectivityManager.NetworkCallback init { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { networkCallback = object : ConnectivityManager.NetworkCallback() { override fun onAvailable(network: Network) { super.onAvailable(network) onConnectionAvailable.invoke() if (shouldStopAfterFirstResponse) { stop() } } override fun onLost(network: Network?) { super.onLost(network) onConnectionLost.invoke() if (shouldStopAfterFirstResponse) { stop() } } } } } fun start() { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { // Decouple from component lifecycle, use application context. // See: https://developer.android.com/reference/android/content/Context.html#getApplicationContext() context.applicationContext.registerReceiver(broadCastReceiver, intentFilter) } else { connectivityManager.registerDefaultNetworkCallback(networkCallback) } } fun stop() { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { context.applicationContext.unregisterReceiver(broadCastReceiver) } else { connectivityManager.unregisterNetworkCallback(networkCallback) } } }

Uso:

val onConnectionAvailable = TODO() val connectivityObserver = ConnectivityObserver(context, onConnectionAvailable) connectivityObserver.start() connectivityObserver.stop()

o:

val onConnectionAvailable = TODO() val onConnectionLost = TODO() ConnectivityObserver(context, onConnectionAvailable, onConnectionLost, shouldStopAfterFirstResponse = true ).start()

No olvide agregar el permiso ACCESS_NETWORK_STATE en su AndroidManifest.xml :

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

Espero con interés leer comentarios útiles y mejoras de usted.


Estoy de acuerdo con la answer sugerida por @rds.

Tenga en cuenta que CONNECTIVITY_ACTION está en desuso en el nivel 28 de API.

Si tiene el requisito de que se detecte el estado de Wifi (conectar / desconectar) a pesar de que la aplicación se haya apagado y desea apuntar a la última versión, entonces no tiene mucha opción.

connectivityManager.registerNetworkCallback(networkRequest, networkCallback) usar connectivityManager.registerNetworkCallback(networkRequest, networkCallback)

La pregunta es que no puedes usar BroadcastReceiver, ¿cómo entonces?

Puede usar JobScheduler o mejor si WorkManager (Solicitud periódica). Por qué Periódico porque si se trata de OneTimeRequest, solo podrá ejecutarse una vez y seguir escuchando mientras su aplicación está en primer plano.

Documentation dice:

Las devoluciones de llamada se seguirán llamando hasta que se cierre la aplicación o se llame al enlace #unregisterNetworkCallback (NetworkCallback)}.

Una vez que la aplicación es eliminada o eliminada de la lista de aplicaciones recientes, networkCallback no podrá escuchar.

Por lo tanto, necesita trabajos periódicos para que la aplicación escuche continuamente. ¿Cuánto debería ser la duración? Eso depende de usted y depende de cada caso.

Sé que es un poco feo, pero así es como es. Un desafío podría ser que si el dispositivo del usuario está en modo Doze o la aplicación está en estado de espera, su trabajo podría retrasarse.


La documentación para Android N establece:

Las aplicaciones dirigidas a Android N no reciben transmisiones de CONNECTIVITY_ACTION, incluso si tienen entradas de manifiesto para solicitar la notificación de estos eventos. Las aplicaciones que se ejecutan en primer plano aún pueden escuchar CONNECTIVITY_CHANGE en su hilo principal si solicitan notificación con un BroadcastReceiver.

Esto significa que aún puede registrar un BroadcastReceiver si su aplicación se está ejecutando en primer plano, para detectar cambios en la conectividad de la red.


Las aplicaciones dirigidas a Android N (Nougat) no reciben transmisiones de CONNECTIVITY_ACTION definidas en el manifiesto (ver Svelte ).

Soluciones posibles:

Consulte también Android O: detectar cambios de conectividad en segundo plano


Lo que quedará en desuso es la capacidad de una aplicación en segundo plano para recibir cambios de estado de conexión de red.

Como dijo David Wasser , aún puede recibir notificaciones de cambios de conectividad si el componente de la aplicación se instancia (no se destruye) y ha registrado su receptor mediante programación en su contexto, en lugar de hacerlo en el manifiesto.

O puede usar NetworkCallback lugar. En particular, deberá anular onAvailable para cambios de estado conectados.

Permítanme redactar un fragmento rápidamente:

public class ConnectionStateMonitor extends NetworkCallback { final NetworkRequest networkRequest; public ConnectionStateMonitor() { networkRequest = new NetworkRequest.Builder().addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR).addTransportType(NetworkCapabilities.TRANSPORT_WIFI).build(); } public void enable(Context context) { ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); connectivityManager.registerNetworkCallback(networkRequest , this); } // Likewise, you can have a disable method that simply calls ConnectivityManager.unregisterNetworkCallback(NetworkCallback) too. @Override public void onAvailable(Network network) { // Do what you need to do here } }


Me encontré con el mismo problema hace unos días y decidí usar esta biblioteca Android-Job

Esta biblioteca utiliza JobSchedular , GcmNetworkManager y BroadcastReceiver según la versión de Android en la que se ejecute la aplicación.

Comenzar un trabajo es bastante fácil

new JobRequest.Builder(DemoSyncJob.TAG) .setRequiresCharging(true) .setRequiresDeviceIdle(false) .setRequiredNetworkType(JobRequest.NetworkType.CONNECTED) // this is what gets the job done .build() .schedule();