Почему обнаружение пиров для Android Wi-Fi Direct так ненадежно?

Я экспериментирую с Android Wi-Fi Direct (или P2P, если хотите). Я думал, что между двумя моими телефонами все работает очень хорошо, но я понял, что у меня проблемы с WifiP2pManager.discoverPeers() и/или WifiP2pManager.requestPeers(). Я наблюдал эти результаты:

  • Никакие пиры не обнаруживаются, и обратные вызовы не запускаются в течение добрых 1+ минут. Я также наблюдаю это через часть Wi-Fi Direct в настройках Android Wi-Fi. Это странно, потому что иногда открытие завершается почти сразу.

  • У меня есть устройство Roku и телефон B рядом с телефоном A. Хотя все они подключены к моему Wi-Fi, Roku появляется только примерно в 10% случаев, в то время как телефоны A и B отображаются друг с другом.

  • Когда я отключил два телефона от всех Wi-Fi и сделал еще одно сканирование, Roku появился (!!!), но телефон B не появился, пока я не обновился как минимум десять раз.

У меня два телефона: Nexus 7 (под управлением 4.4.4) и Nexus 5 (под управлением 5.0).


person Mark Herscher    schedule 15.12.2014    source источник


Ответы (4)


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

Я думаю, две самые раздражающие вещи были:

  • Недокументированный UNKNOWN_ERROR (я думаю, что его int код был -3), который добавляется в ActionListener onFailure. Кажется, это какая-то проблема с самим демоном Wi-Fi. Единственное, что, кажется, работает, чтобы предотвратить это, — это сброс WiFi, прежде чем вы даже начнете возиться с прямым WiFi.

  • Что-то находится в неправильном состоянии для вызова вашего метода, например, если WIFI_P2P_STATE_CHANGED_ACTION не был получен вашим широковещательным приемником с WIFI_P2P_STATE_ENABLED или если "ваше_устройство" не получило должного status в WIFI_P2P_THIS_DEVICE_CHANGED_ACTION. Обычно это приводит к onFailure вызовите один из ваших ActionListener s (например, с ERROR или < href="http://developer.android.com/reference/android/net/wifi/p2p/WifiP2pManager.html#BUSY" rel="nofollow noreferrer">BUSY причина сбоя).

person Bartek Lipinski    schedule 15.12.2014

По моему опыту, надежно. После тонны попыток я получил надежный работоспособный поток, подобный этому:

...
wifiP2pManager.clearLocalServices(wifiP2pChannel, new WifiP2pManager.ActionListener() {
            @Override
            public void onSuccess() {
                HashMap<String, String> record = new HashMap<>();
                record.put("name", "Amos");
                WifiP2pDnsSdServiceInfo serviceInfo = WifiP2pDnsSdServiceInfo.newInstance(AppConfig.DNS_SD_SERVICE_NAME, AppConfig.DNS_SD_SERVICE_TYPE, record);
                wifiP2pManager.addLocalService(wifiP2pChannel, serviceInfo, new WifiP2pManager.ActionListener() {
                    @Override
                    public void onSuccess() {
                        wifiP2pManager.setDnsSdResponseListeners(wifiP2pChannel, WifiDirectFragment.this, WifiDirectFragment.this);
                        wifiP2pManager.clearServiceRequests(wifiP2pChannel, new WifiP2pManager.ActionListener() {
                            @Override
                            public void onSuccess() {
                                wifiP2pManager.addServiceRequest(wifiP2pChannel, WifiP2pDnsSdServiceRequest.newInstance(), new WifiP2pManager.ActionListener() {
                                    @Override
                                    public void onSuccess() {
                                        wifiP2pManager.discoverPeers(wifiP2pChannel, new WifiP2pManager.ActionListener() {
                                            @Override
                                            public void onSuccess() {
                                                wifiP2pManager.discoverServices(wifiP2pChannel, new WifiP2pManager.ActionListener() {
                                                    @Override
                                                    public void onSuccess() {
                                                        // this is my recursive discovery approach                                                            
                                                        handler.postDelayed(discoveryRunnable, AppConfig.DNS_SD_SERVICE_DISCOVERABLE_DURATION_S * 1000);
                                                    }

                                                    @Override
                                                    public void onFailure(int code) {
                                                    }
                                                });
                                            }

                                            @Override
                                            public void onFailure(int code) {
                                            }
                                        });
                                    }

                                    @Override
                                    public void onFailure(int code) {
                                    }
                                });
                            }

                            @Override
                            public void onFailure(int code) {
                            }
                        });
                    }

                    @Override
                    public void onFailure(int code) {
                    }
                });
            }

            @Override
            public void onFailure(int code) {
            }
        });
person Amos    schedule 04.11.2016
comment
Для тех, кто использует это в качестве руководства по реализации в Xamarin, я добился великолепного успеха с этим шаблоном — я просто поместил все функции в службу Wi-Fi и передал службу Wi-Fi всем прослушивателям действий в том же порядке, что и поместите здесь, вызывая следующий шаг в каждом соответствующем методе успеха в цепочке, браво, Амос, очень признателен, работает как шарм! - person Xamtastic; 25.11.2019
comment
Что делает discoveryRunnable? - person Code Wiget; 17.04.2020

Мне удалось «решить» проблемы, связанные с тем, что некоторые телефоны не появлялись, запрашивая одноранговое обнаружение каждые 10 секунд. Я думаю, что столкнулся с этим, потому что один телефон всегда был хостом, и я не беспокоился о том, чтобы он обнаруживал одноранговые узлы (потому что он не пытался присоединиться к ним), а Wifi Direct собирался спать на хост-телефоне. Я ничего не делаю с результатами пиров, но это пробуждает систему Wifi Direct. Вероятно, есть лучший метод вызова, но я не уверен, что это такое. Если бы мне пришлось угадывать, я бы сказал, что трачу время автономной работы.

person Mark Herscher    schedule 16.12.2014

У меня была действительно большая проблема с установлением соединения между устройствами:

  • первое устройство включает обнаружение одноранговых узлов
  • второе устройство включает обнаружение одноранговых узлов
  • одно устройство пытается установить соединение со вторым
  • иногда работает, иногда нет (я бы сказал 50/50)

Я предполагаю, что проблема заключалась в соглашении о владельце группы (я также пытался изменить параметр groupOwnerIntent, чтобы указать, кто должен быть владельцем группы, но это не помогло).

Итак, что я сделал?

Я меняю поток на:

  • одно устройство создает группу (mManager.createGroup(...)), поэтому это устройство всегда является владельцем группы
  • второе устройство подключается к владельцу группы
  • whooala, теперь очень редко можно застрять в состоянии invited.
person Cililing    schedule 10.07.2019
comment
обратите внимание, что тогда второе устройство подключается к этой сети вместо обычной точки доступа, а не в дополнение к ней. так что вы теряете это преимущество Wi-Fi прямо на клиентском устройстве - person xuiqzy; 29.03.2020