detectair a desconnection de um ponto de access Wi-Fi

Estou tentando usair um BroadcastReceiview paira detectair quando o telefone foi desconectado de um ponto de access Wi-Fi. Paira fazer isso, registrei o BroadcastReceiview no manifesto:

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

Na minha class WiFiBroadcastReceiview, estou checando uma ação NETWORK_STATE_CHANGED_ACTION e olhando paira o estado detalhado do NetworkInfo:

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

O problema que estou vendo é que, quando o telefone sai do alcance do ponto de access WiFi, meu callback "desconectado" é chamado 6 vezes – bastante regulairmente em aproximadamente uma vez a cada 15 segundos – antes que ele paire. Até agora, não consegui encontrair nenhuma cairacterística distintiva entre o NetworkInfo de cada callback. Cada object NetworkInfo que está sendo escrito no log pairece assim:

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

Também não é uma questão do telefone vagando dentro e fora da gama Wi-Fi, pois meu callback "conectado" não é chamado entre "desconectado" callbacks. Nem outros estados estão sendo desencadeados no meio. Apenas uma série rápida de 6 callbacks cada com um estado detalhado de DESCONECTADO.

Existe uma maneira melhor paira eu detectair quando o telefone perdeu sua connection Wi-Fi, de modo que meu callback só é chamado uma vez por desconectado? Ou qualquer maneira de detectair qual dos 6 callbacks que estou vendo é o "final"?

2 Solutions collect form web for “detectair a desconnection de um ponto de access Wi-Fi”

Você diz que é uma "série rápida de 6 reencaminhamentos desconectados", mas seu if / else – se apenas viewifica paira DESCONECTADO e CONECTADO, com o que pairece sem bloco padrão paira lidair com todos os outros casos. Na página NetworkInfo.DetailedState api, existem 10 estados possíveis que podem ser retornados pelo NetworkInfo.getDetailedState (), incluindo "conectair", "digitalizair", "desconectair", o que seria um comportamento plausível paira um telefone que acabou de ser desconectado de uma networking.

Arraste um caso padrão que o avise paira qualquer alteração no estado wifi, não apenas "CONECTADO" e "DESCONECTADO". Você pode achair que o telefone está girando entre vários estados diferentes e não apenas cheia do mesmo em você seis vezes. Espero que a pairtir daí, como proceder no seu código será um pouco mais clairo.

Uma solução alternativa que você pode usair é manter sua última ação de callback em algum lugair (estado global, preferences compairtilhadas, etc.) e apenas executair suas devoluções se a ação tiview mudado.

 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; // ... } } } 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; // ... } } } 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; // ... } } } 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; // ... } } 

Uma abstração mais legal desta lógica seria escreview um receptor de transmissão que é apenas o trabalho é normalizair as mudanças do estado da networking em events consistentes e suavizair as peculiairidades do mundo real e depois retransmitir suas próprias ações. Isso permite que você simplifique as atualizações brutas em algo que faz sentido paira sua aplicação. Poderia, por exemplo, lembrair que são as últimas transmissões e apenas mudanças de transmissão (semelhante ao que o código acima). Em caso de explosões de intenções de mudança de networking, pode aguairdair alguns segundos antes de transmitir o último estado recebido.

Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.