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

Android 检测WiFi接入点的断开连接,android,wifi,broadcastreceiver,disconnect,Android,Wifi,Broadcastreceiver,Disconnect,我正在尝试使用广播接收器检测手机何时与WiFi接入点断开连接。为此,我在清单中注册了BroadcastReceiver: <receiver android:name="com.eshayne.android.WiFiBroadcastReceiver"> <intent-filter> <action android:name="android.net.wifi.STATE_CHANGE" /> </intent-fil

我正在尝试使用广播接收器检测手机何时与WiFi接入点断开连接。为此,我在清单中注册了BroadcastReceiver:

<receiver android:name="com.eshayne.android.WiFiBroadcastReceiver">
    <intent-filter>
        <action android:name="android.net.wifi.STATE_CHANGE" />
    </intent-filter>
</receiver>
我看到的问题是,当手机离开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个回调中的哪一个是“最终”回调?

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


抛出一个默认案例,提醒您wifi状态的任何变化,而不仅仅是“已连接”和“已断开”。你可能会发现手机在几个不同的州之间旋转,而不仅仅是对着同一个手机射击六次。希望从此以后,代码中的处理方法会更加清晰。

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

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

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

这里到底是什么问题?当您说手机在第一次广播后没有重新连接时,这6个连接中的任何一个都没有另一个好吗?问题是我不想让我的广播接收器执行六次相同的断开连接处理逻辑。谢谢。我应该澄清一下——在检查连接或断开连接之前,我实际上记录了整个网络信息。它们都断开了。我已经更新了我的原始帖子,以显示所有日志条目的外观。如果您能想出其他方法来检查每个回调以尝试区分它们,我将尝试一下。
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;
    // ...
  }
}