2011-02-18 17 views
10

Estoy tratando de usar un BroadcastReceiver para detectar cuando el teléfono se ha desconectado de un punto de acceso WiFi. Para ello, he registrado mi BroadcastReceiver en el manifiesto:detección de desconexión de un punto de acceso WiFi

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

En mi clase WiFiBroadcastReceiver, yo soy el registro de una acción NETWORK_STATE_CHANGED_ACTION y mirando en el estado detallado de la 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 I' Lo que veo es que cuando el teléfono sale del rango del punto de acceso WiFi, mi devolución de llamada "desconectada" se llama 6 veces, con bastante frecuencia aproximadamente una vez cada 15 segundos, antes de que se detenga. Hasta ahora no he podido encontrar ninguna característica distintiva entre cada NetworkInfo de devolución de llamada. Cada objeto NetworkInfo que se escriben en el registro es el siguiente:

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 del teléfono entraba y salía de la gama Wi-Fi, ya que mi devolución de llamada "conectado" no se llama en el medio devoluciones de llamada "desconectado" . Tampoco se activan otros estados en el medio. Solo una serie rápida de 6 devoluciones de llamada cada una con un detallado estado de DESCONECTADO.

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

+0

¿Cuál es exactamente el problema aquí? Cuando dice que el teléfono no se está reconectando después de la primera transmisión, ¿no hay ninguno de los 6 tan bueno como el otro? –

+0

El problema es que no quiero que mi receptor de difusión realice la misma lógica de manejo de desconexión seis veces. – eshayne

Respuesta

2

Dice que es una "serie rápida de 6 devoluciones de llamada desconectadas", pero su if/else-si solo comprueba si está DESCONECTADO y CONECTADO, con lo que parece no ser un bloque predeterminado para manejar todos los demás casos. Desde la página api NetworkInfo.DetailedState, hay 10 estados posibles que NetworkInfo.getDetailedState() podría devolver, incluidos "conectar", "escanear", "desconectar", todo lo cual sería un comportamiento plausible para un teléfono que acaba de desconectarse de un red.

Deshágase de un caso predeterminado que lo avise de cualquier cambio en el estado wifi, no solo "CONECTADO" y "DESCONECTADO". Puede encontrar que el teléfono está girando entre varios estados diferentes, y no solo disparándole el mismo seis veces. Esperemos que a partir de ahí, cómo proceder en su código será un poco más claro.

+0

Gracias. Debería haber aclarado: en realidad estoy registrando cada NetworkInfo completo, antes de verificar si está CONECTADO o DESCONECTADO. Están todos DESCONECTADOS. Actualicé mi publicación original para mostrar cómo se ven todas las entradas de registro. Si puede pensar en otra cosa para verificar cada devolución de llamada para tratar de distinguirlos, lo intentaré. – eshayne

0

Una solución alternativa que puede utilizar es mantener su última acción de devolución de llamada en algún lugar (estado global, preferencias compartidas, etc.) y solo ejecutar sus 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 abstracción más bonito de esta lógica sería escribir un receptor de radiodifusión cuya única función es la normalización de los cambios de estado de red en eventos consistentes y suavizar las peculiaridades del mundo real y, a continuación, volver a emitir 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 que son las últimas transmisiones y solo 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 transmitir el último estado que recibió.

Cuestiones relacionadas