Why is discovering peers for Android Wi-Fi Direct

2020-02-20 05:37发布

I am experimenting with Android's Wi-Fi Direct (or P2P if you prefer). I thought it was working very nicely between my two phones, but I realized I am encountering issues with the WifiP2pManager.discoverPeers() and/or WifiP2pManager.requestPeers(). I have observed these results:

  • No peers are discovered and no callbacks are fired for a good 1+ minute. I observe this through the Wi-Fi Direct portion of the Android Wi-Fi settings as well. This is odd because sometimes the discovery completes almost immediately.

  • I have a Roku device and phone B sitting next to phone A. While all are connected to my Wi-Fi, the Roku only appears ~10% of the time, while phones A and B appear to each other.

  • When I disconnected the two phones from all Wi-Fi and did another scan, the Roku showed up (!!!) but phone B did not until I had refreshed at least ten times.

My two phones are a Nexus 7 (running 4.4.4) and a Nexus 5 (running 5.0).

4条回答
Root(大扎)
2楼-- · 2020-02-20 05:51

I had a really big problem with establishing connection between devices:

  • first device turns on peer discovery
  • second device turns on peer discovery
  • one device tries to establish connection with the second one
  • sometimes it works, sometimes not (I would say 50/50)

I guess the issue was the group owner negotiation (I've tried change groupOwnerIntent param also to force who should be group owner, but it didn't helped).

So, what did I do?

I change flow to:

  • one device creates group (mManager.createGroup(...)), so this device is always a group owner
  • second devices connects with group owner
  • whooala, now is very rare to stuck on invited state.
查看更多
小情绪 Triste *
3楼-- · 2020-02-20 06:02

I was able to "solve" the problems of some phones not appearing by requesting peer discovery every 10 seconds. I think I was running into this because one phone was always the host and I didn't bother to have it discover peers (because it doesn't try to join them), and the Wifi Direct was going to sleep on the host phone. I don't do anything with the peer results, but it wakes up the Wifi Direct system. There's probably a better method to call but I'm not sure what it is. If I had to guess I'd say I'm wasting some battery life.

查看更多
我想做一个坏孩纸
4楼-- · 2020-02-20 06:06

I've been recently developing an application with a connection system based on WiFi Direct (with WiFi P2P Service Discovery) and the one thing I can most certainly say is that the whole thing is a huge pain in the ... . Mostly because of the lack of documentation but also because when developing a wifi-direct-based solution you need to pay attention to basically everything (especially to all callbacks from listeners) before making any method call.

Two most annoying things were I guess:

查看更多
做个烂人
5楼-- · 2020-02-20 06:08

From my experience it's reliable. After tons of trying, I got the robust workable flow like this:

...
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) {
            }
        });
查看更多
登录 后发表回答