gpt4 book ai didi

android - 当 Wi-Fi Direct 范围内的对等点不再可用时,如何通知?

转载 作者:可可西里 更新时间:2023-11-01 18:57:51 27 4
gpt4 key购买 nike

我正在开发基于使用 Wifi Direct API 的 Android 应用程序。我已在我的 Activity 中注册一个 BroadcastReceiver为了收到有关以下 Wifi Direct 事件的通知:

WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION 
WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION
WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION
WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION

我相信对等点列表中的任何更改(在 Wifi Direct 范围内包含或排除对等点)都可能触发 BroadcastReceiver .在我的应用程序中,当找到一个新的对等点时,它的名称正确地包含在 ListView 中。 ,但是如果对端离开无线范围(或者如果我关闭了它的 Wi-Fi 接口(interface)), BroadcastReceiver不被调用(更具体地说,
WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION

事件未触发),对等体名称保留在 ListView .

我想知道是否有任何方法来处理这个问题,因为对等名称包含在 ListView 中。 ,但从不排除。我已经考虑过重新初始化 Channel 和 WifiP2pManager实例,但我相信这将断开所有对等点。

最佳答案

I believed that any change in the list of peers (the inclusion or exclusion of a peer in the Wifi Direct range) could trigger the BroadcastReceiver.



是的,我认为这应该发生。

In my app, when a new peer is found, its name is correctly included in a ListView, but if the peer leaves the wireless range (or if I turn off its Wi-Fi interface), the BroadcastReceiver is not invoked (more specifically, the WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION event is not triggered), and the peer name remains in the ListView.



我们可以尝试挖掘源代码,看看是否可以解释这种行为。

注意:我没有提供解决方案。但是,以下研究可能会帮助您更好地理解“问题”。

我们将从这里开始: WifiP2pSettings Link

这是您在转到设置 > Wifi > Wifi-Direct 时看到的 fragment 。如果您仔细阅读代码,您会注意到其实现与 WifiDirectDemo 非常相似。项目 - BroadcastReceiver监听相同的四个 Action (另外两个 - 一个用于 UI 更新)。我们查看这个 fragment 的原因是检查演示本身是否存在缺陷。但是,看起来演示还不错。

继续 - 让我们看看谁在直播 WIFI_P2P_PEERS_CHANGED_ACTION - 最终,我们有兴趣找出为什么在设备离线/超出范围时不会立即发生这种情况。这将我们带到 WifiP2pService Link .

方法 WifiP2pService # sendPeersChangedBroadcast()发出广播:
private void sendPeersChangedBroadcast() {
final Intent intent = new Intent(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
intent.putExtra(WifiP2pManager.EXTRA_P2P_DEVICE_LIST, new WifiP2pDeviceList(mPeers));
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
}

从看 WifiP2pService ,你可以看出 sendPeersChangedBroadcast()被调用以响应几个事件。我们对此感兴趣: WifiMonitor.P2P_DEVICE_LOST_EVENT Link :
....
case WifiMonitor.P2P_DEVICE_LOST_EVENT:
device = (WifiP2pDevice) message.obj;
// Gets current details for the one removed
device = mPeers.remove(device.deviceAddress);
if (device != null) {
sendPeersChangedBroadcast();
}
break;
....
WifiMonitor # handleP2pEvents(String)负责发送登陆上述 case的消息.上链找到 MonitorThread - WifiMonitor 中的静态内部类. MonitorThread # dispatchEvent(String)调用 handleP2pEvents(String)方法。

最后,有趣的事情。看 run() MonitorThread的方法:
private static class MonitorThread extends Thread {

....

public void run() {
//noinspection InfiniteLoopStatement
for (;;) {
String eventStr = mWifiNative.waitForEvent();
....
}
}

....
}
  • 首先,我们处于一个无限循环中。
  • 二、mWifiNative.waitForEvent()告诉我这可能是一个阻塞调用。

  • 这两点放在一起向我表明,我不会因此得到迅速的回应——嗯,绝对没有什么“即时的”。我们通过上链达到的方法 - MonitorThread # dispatchEvent(String) - 从这个无限循环内部调用。

    让我们检查一下是否有东西可以支持我们有根据的猜测:

    看看 WifiNative类(class) Link ,尤其是方法 setScanInterval(int) .此方法从类 WifiStateMachine 中调用 Link .过方法 processMessage(Message) :
    ....
    case WifiP2pService.P2P_CONNECTION_CHANGED:
    NetworkInfo info = (NetworkInfo) message.obj;
    mP2pConnected.set(info.isConnected());
    if (mP2pConnected.get()) {
    int defaultInterval = mContext.getResources().getInteger(
    R.integer.config_wifi_scan_interval_p2p_connected);
    long scanIntervalMs = Settings.Global.getLong(mContext.getContentResolver(),
    Settings.Global.WIFI_SCAN_INTERVAL_WHEN_P2P_CONNECTED_MS,
    defaultInterval);

    // ====>> Interval defined here
    mWifiNative.setScanInterval((int) scanIntervalMs/1000);
    } else if (mWifiConfigStore.getConfiguredNetworks().size() == 0) {
    if (DBG) log("Turn on scanning after p2p disconnected");
    sendMessageDelayed(obtainMessage(CMD_NO_NETWORKS_PERIODIC_SCAN,
    ++mPeriodicScanToken, 0), mSupplicantScanIntervalMs);
    }
    ....

    注意 defaultInterval在第一个 if block .它正在请求 R.integer.config_wifi_scan_interval_p2p_connectedconfig.xml 中定义 Link作为:
    <!-- Integer indicating wpa_supplicant scan interval when p2p is connected in milliseconds -->
    <integer translatable="false" name="config_wifi_scan_interval_p2p_connected">60000</integer>

    60000 毫秒。那是1分钟。所以,如果 Settings.Global.WIFI_SCAN_INTERVAL_WHEN_P2P_CONNECTED_MS未设置,扫描将间隔 1 分钟。

    因为, WIFI_SCAN_INTERVAL_WHEN_P2P_CONNECTED_MS被置于全局设置下,我们无法更改它。事实上,它甚至无法读取。意思是,我们这里唯一的保证是节点列表将在一分钟内刷新。间隔当然可以因品牌而异。

    为了验证这一点,我在华硕平板电脑和戴尔平板电脑上运行了演示。就像你说的,设备上线很快就被注意到了(在发现阶段)。在关闭 wifi 时,我记录了响应。离线设备自动从列表中删除 - 有相当长的延迟。戴尔平板电脑接近 60 seconds注意到华硕离线。另一方面,华硕拿下了 45 seconds .

    对我来说,这似乎是 android 强制执行的限制。我说不出为什么。我希望这里有人可以为您提供解决方案 - 可能会进行这项研究并进一步探索。但是,如果(目前)不存在解决方案,我不会感到惊讶。

    关于android - 当 Wi-Fi Direct 范围内的对等点不再可用时,如何通知?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21072081/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com