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:
- Analizar todos los dispositivos wifi cerca del teléfono
- Conecte dos teléfonos android con wi-fi (sin laptop o punto de acceso) y envíe el archivo
- Detección de redes WiFi abiertas
- gama de distancias en las que trabaja directamente Wi-Fi
- ¿Tiene el emulador de dispositivos Android una dirección MAC?
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"?
- Cómo detener la exploración wifi en Android?
- Cómo enviar MAC marco de datos de difusión con Android AP
- Conectarse a WiFi abierto
- Wifi conexión múltiple directa ad-hoc
- ¿Cómo puedo imprimir a través de una impresora WiFi en Android mediante una conexión Wi-Fi Direct?
- Escanear Wi-Fi de Android: Filtrar impresoras de ScanResult
- Compartir imágenes desde un dispositivo Android a otro a través de WiFi
- No se puede conectar a Android a través de ADB a través de wifi - ¿Necesito acceso root?
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ó.
- Mostrar nuevos elementos en la parte superior de un ListView
- La ejecución de Instrumentation falló debido a 'java.lang.NullPointerException'