Detectar la desconexión desde un punto de acceso WiFi

Estoy tratando de usar un BroadcastReceiver para detectar cuando el teléfono se ha desconectado de un punto de acceso WiFi. Para ello, registré mi BroadcastReceiver en el manifiesto:

<receiver android:name="com.eshayne.android.WiFiBroadcastReceiver"> <intent-filter> <action android:name="android.net.wifi.STATE_CHANGE" /> </intent-filter> </receiver> 

En mi clase de WiFiBroadcastReceiver, estoy comprobando para una acción de NETWORK_STATE_CHANGED_ACTION y mirando el estado detallado del NetworkInfo:

 if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) { NetworkInfo info = (NetworkInfo)intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); android.util.Log.d("com.eshayne.android.WiFiBroadcastReceiver", "network state change - detailedState=" + info.getDetailedState() + ": " + info.toString()); if (info.getDetailedState() == DetailedState.DISCONNECTED) { ... } else if (info.getDetailedState() == DetailedState.CONNECTED) { ... } 

El problema que estoy viendo es que cuando el teléfono sale del alcance del punto de acceso de WiFi, mi devolución de llamada "desconectada" se llama 6 veces – bastante regularmente sobre una vez cada 15 segundos – antes de que se detenga. Hasta ahora no he sido capaz de encontrar ninguna característica distintiva entre NetworkInfo de cada devolución de llamada. Cada objeto de NetworkInfo que se escribe en el registro se ve así:

 02-18 10:16:51.918 D/com.eshayne.android.WiFiBroadcastReceiver( 1511): network state change - detailedState=DISCONNECTED: NetworkInfo: type: WIFI[], state: DISCONNECTED/DISCONNECTED, reason: (unspecified), extra: (none), roaming: false, failover: false, isAvailable: true 

Tampoco es un problema de que el teléfono entre y salga de la gama WiFi, ya que mi llamada "conectada" no se llama entre llamadas "desconectadas". Tampoco se activan otros estados entre ellos. Sólo una serie rápida de 6 callbacks cada uno con un estado detallado de DISCONNECTED.

¿Hay una manera mejor para mí para detectar cuando el teléfono ha perdido su conexión WiFi, por lo que mi devolución de llamada sólo se llama una vez por desconectar? ¿O cualquier forma de detectar cuál de las 6 llamadas que estoy viendo es la "final"?

Usted dice que es una "serie rápida de 6 callbacks desconectados", pero su if / else-si sólo comprueba para DISCONNECTED y CONNECTED, con lo que parece un bloque predeterminado para manejar todos los demás casos. De la página api de NetworkInfo.DetailedState , hay 10 estados posibles que podrían ser devueltos por NetworkInfo.getDetailedState (), incluyendo "conectar", "escanear", "desconectar", todo lo cual sería comportamiento plausible para un teléfono que acaba de desconectarse Desde una red.

Deseche un caso predeterminado que le avisa de cualquier cambio en el estado wifi, no sólo "CONECTADO" y "DESCONECTADO". Usted puede encontrar que el teléfono está girando entre varios estados diferentes, y no sólo shotgunning el mismo en usted seis veces. Esperemos que de allí, cómo proceder en su código será un poco más claro.

Una solución que podría utilizar es mantener la última acción de devolución de llamada en algún lugar (estado global, preferencias compartidas, etc.) y sólo ejecutar las devoluciones de llamada si la acción ha cambiado.

 enum NetworkCallbackAction { None, Disconnected, Connected }; NetworkCallbackAction lastHandledAction = NetworkCallbackAction.None; // ... if (info.getDetailedState() == DetailedState.DISCONNECTED) { if (lastHandledAction != NetworkCallbackAction.Disconnected) { lastHandledAction = NetworkCallbackAction.Disconnected; // ... } } else if (info.getDetailedState() == DetailedState.CONNECTED) { if (lastHandledAction != NetworkCallbackAction.Connected) { lastHandledAction = NetworkCallbackAction.Connected; // ... } } 

Una mejor abstracción de esta lógica sería escribir un receptor de difusión que es único trabajo es normalizar los cambios de estado de la red en eventos consistentes y suavizar las peculiaridades del mundo real, y luego volver a difundir sus propias acciones. Esto le permite simplificar las actualizaciones sin procesar en algo que tenga sentido para su aplicación. Podría, por ejemplo, recordar sus últimas transmisiones y sólo los cambios de difusión (similar a lo que hace el código anterior). En caso de ráfagas de intentos de cambio de red podría esperar unos segundos antes de difundir el último estado que recibió.

  • Cómo evitar el retraso en los mensajes de GCM de Android / cambio de latidos del corazón
  • ¿Cómo determinar qué estándar es utilizado por wifi ap / network?
  • Conexión WiFi a través de Android
  • Dispositivo inalámbrico ADB no autorizado
  • Obtener la intensidad de la señal de WIFI y datos móviles
  • Android: Fuerza los datos que se envían a través de radio vs WiFi
  • ¿Hacer de un dispositivo móvil un control remoto para una tableta?
  • Abrir la aplicación cuando se conecta con wifi
  • Hotspot multiplexado en Android
  • ¿Es posible eliminar los grupos Wifi Direct de Android programados?
  • Instalación / Acceso a Certs para VPN / WIFI mediante programación en Android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.