6

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).

Brendan
  • 1,403
  • 4
  • 18
  • 37
Mark Herscher
  • 1,761
  • 2
  • 19
  • 32

4 Answers4

8

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:

Bartek Lipinski
  • 30,698
  • 10
  • 94
  • 132
5

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) {
            }
        });
Amos
  • 2,222
  • 1
  • 26
  • 42
  • 1
    For those using this as a guide to implement it in Xamarin, I've had splendid success with this pattern - I merely put all of the functions in a Wifi Service, and passed the wifi service into all the Action Listeners in the same order as put here, invoking the next step in each respective Success method in the chain, bravo Amos, much appreciative, works like a charm! – Xamtastic Nov 24 '19 at 21:23
  • What does the discoveryRunnable do? – Code Wiget Apr 17 '20 at 14:26
4

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.

Mark Herscher
  • 1,761
  • 2
  • 19
  • 32
1

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.
Cililing
  • 4,303
  • 1
  • 17
  • 35
  • note that then, the second device connects to this network instead of a usual access point and not in addition to it. so you lose that benefit of wifi direct on the client device – xuiqzy Mar 29 '20 at 12:32
  • What benefit exactly? – HasIEluS Jan 05 '23 at 05:57