обнаружение отключения от точки доступа WiFi - PullRequest
10 голосов
/ 18 февраля 2011

Я пытаюсь использовать BroadcastReceiver для определения, когда телефон отключился от точки доступа WiFi.Для этого я зарегистрировал свой BroadcastReceiver в манифесте:

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

В своем классе WiFiBroadcastReceiver я проверяю действие NETWORK_STATE_CHANGED_ACTION и просматриваю подробное состояние 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) {
        ...
    }

Проблема, которую я вижу, состоит в том, что, когда телефон покидает зону действия точки доступа WiFi, мой «отключенный» обратный вызов вызывается 6 раз - довольно регулярно, примерно раз в 15 секунд, - до того, как он останавливается.До сих пор я не смог найти никаких отличительных характеристик между NetworkInfo каждого обратного вызова.Каждый объект NetworkInfo, записываемый в журнал, выглядит следующим образом:

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

Это также не проблема того, что телефон может входить и выходить из диапазона WiFi, поскольку мой «подключенный» обратный вызов не вызывается между «отключенным»"обратные вызовы.Никаких других состояний не происходит между ними.Просто быстрая серия из 6 обратных вызовов, каждый с подробным состоянием ОТКЛЮЧЕНО.

Есть ли лучший способ для меня определить, когда телефон потерял соединение WiFi, чтобы мой обратный вызов вызывался только один раз за отключение?Или какой-нибудь способ определить, какой из 6 обратных вызовов, которые я вижу, является «последним»?

Ответы [ 2 ]

2 голосов
/ 19 февраля 2011

Вы говорите, что это «быстрая серия из 6 отключенных обратных вызовов», но ваш if / else-if только проверяет наличие DISCONNECTED и CONNECTED, что похоже на отсутствие блока по умолчанию для обработки всех других случаев.На странице API NetworkInfo.DetailedState есть 10 возможных состояний, которые могут быть возвращены NetworkInfo.getDetailedState (), включая «подключение», «сканирование», «отключение», и все это будет правдоподобно длятелефон, который только что был отключен от сети.

Сбросить случай по умолчанию, который предупреждает вас о любом изменении состояния Wi-Fi, а не только "ПОДКЛЮЧЕНО" и "ОТКЛЮЧЕНО".Возможно, вы обнаружите, что телефон вращается между несколькими состояниями, а не просто выстрелил один раз в вас шесть раз.Будем надеяться, что дальнейшие действия в вашем коде будут немного понятнее.

0 голосов
/ 21 февраля 2012

Один из обходных путей, который вы можете использовать, - это поддерживать где-то свое последнее действие обратного вызова (глобальное состояние, общие настройки и т. Д.) И запускать обратные вызовы только в том случае, если действие изменилось.

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

Более приятная абстракцияэта логика заключалась бы в том, чтобы написать широковещательный приемник, единственная задача которого - нормализовать изменения состояния сети в согласованные события и сгладить причуды реального мира, а затем повторно транслировать свои собственные действия.Это позволяет упростить необработанные обновления во что-то, что имеет смысл для вашего приложения.Например, он может вспомнить последние трансляции и только изменения трансляции (аналогично тому, что делает код выше).В случае всплесков намерения изменить сеть может подождать несколько секунд, прежде чем передать последнее полученное состояние.

...