检测与WiFi接入点的断开连接

时间:2011-02-18 16:44:57

标签: android wifi broadcastreceiver disconnect

我正在尝试使用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个回调,每个回调都有详细的DISCONNECTED状态。

我是否有更好的方法来检测手机何时丢失了WiFi连接,以便每次断开连接只会调用一次我的回叫?或者以任何方式检测我看到的6个回调中的哪一个是“最终”回调?

2 个答案:

答案 0 :(得分:2)

你说它是“6个断开连接的回调的快速系列”,但你的if / else-if只检查DISCONNECTED和CONNECTED,看起来没有默认块来处理所有其他情况。从NetworkInfo.DetailedState api页面,NetworkInfo.getDetailedState()可以返回10种可能的状态,包括“连接”,“扫描”,“断开连接”,所有这些状态对于仅仅是电话来说是合理的行为与网络断开连接。

抛出一个默认情况,提醒您在wifi状态下的任何更改,而不仅仅是“已连接”和“已断开连接”。您可能会发现手机在几种不同状态之间旋转,而不仅仅是在您身上拍摄六次相同的手机。希望从那里开始,如何继续使用您的代码将更加清晰。

答案 1 :(得分:0)

您可以使用的一种解决方法是在某处维护您的上一次回调操作(全局状态,共享首选项等),并且只有在操作发生更改时才运行您的回调。

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

这种逻辑的一个更好的抽象是编写一个广播接收器,他唯一的工作就是将网络状态变化规范化为一致的事件并消除现实世界的怪癖,然后重新广播自己的行为。这使您可以将原始更新简化为对您的应用程序有意义的内容。例如,它可以记住它的最后一次广播并且仅广播变化(类似于上面的代码所做的)。如果发生网络更改意图突发,它可能会等待几秒钟,然后再广播收到的最后一个状态。