Search code examples
androidwifi-directwifimanagerwifip2p

Android Wi-Fi Direct P2P connect to multiple devices


I'm having issues trying to connect to multiple devices running the same app. The workflow of my app is:

  1. one device calls discover peers (see code A)
  2. once peers are discovered I display an AlertDialog that allows the user to select which peers they want to connect to (see code B)
  3. once the user selects the devices they want to connect to I attempt to loop through the WifiP2pDeviceList and call the connect method on each of the passed in device (I always set the intent of the current device as the group owner) (see code C)
  4. once connection is made I transfer some data....

Issue: In step 3, when I call the connect method, the code connects to the first device without any problems, but when it gets to the second loop iteration to connect to the second or third device that was selected I get a failure with reason code 2 (Busy). Why is this happening? When I only connect to one device it all works fine, only when I attempt to connect to more than one is when I have the problems? What am I doing wrong? I can't find any examples of how to connect to multiple devices...any help is greatly appreciated.

Code A: (discover peers)

private WifiP2pManager mManager;    

mManager.discoverPeers(mChannel, new WifiP2pManager.ActionListener() {
                @Override
                public void onSuccess() {
                    onInitiateDiscovery();
                }

                @Override
                public void onFailure(int reasonCode) {
                    Toast.makeText(getActivity(), "Discovery Failed: " + getReascodeText(reasonCode), Toast.LENGTH_SHORT).show();
                }
            });

Code B: (select peers you want to connect to)

public void onPeersAvailable(WifiP2pDeviceList peers) {
        final ArrayList<Integer> itemsSelected = new ArrayList<>();

        // Out with the old, in with the new.
        mPeers.clear();
        mPeers.addAll(peers.getDeviceList());
        CharSequence[] cs = StringUtils.getDeviceNames(mPeers);

        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setTitle("Who do you want to share with?");
        builder.setMultiChoiceItems(cs, null, new DialogInterface.OnMultiChoiceClickListener() {
            public void onClick(DialogInterface dialog, int selectedItemId, boolean isChecked) {
                if (isChecked) {
                    itemsSelected.add(selectedItemId);
                } else if (itemsSelected.contains(selectedItemId)) {
                    itemsSelected.remove(Integer.valueOf(selectedItemId));
                }
            }
        }).setPositiveButton("Done!", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int id) {

                WifiP2pDevice wifiP2pDevice = mPeers.get(itemsSelected.get(0));
                List<WifiP2pDevice> devices = extractSelectedDevices(itemsSelected,mPeers);
                numConnections = devices.size();
                connect(devices);
            }
        });

        mPeerSelectionDialog = builder.create();
        mPeerSelectionDialog.show();
}

Code C: (connect to selected devices)

public void connect(List<WifiP2pDevice>  devices) {

    for(WifiP2pDevice device: devices) {
        WifiP2pConfig config = new WifiP2pConfig();
        config.deviceAddress = device.deviceAddress;
        config.wps.setup = WpsInfo.PBC;
        config.groupOwnerIntent = 15;


        mManager.connect(mChannel, config, new WifiP2pManager.ActionListener() {

            @Override
            public void onSuccess() {
                // WiFiDirectBroadcastReceiver will notify us. Ignore for now.
                System.out.println("successfully connected!!");
                Log.d(MultiImageSelectorFragment.TAG, ">>>>>>>>>>>>>>>>>>>>>!!Successfully Connected!<<<<<<<<<<<");

            }

            @Override
            public void onFailure(int reason) {

                Toast.makeText(getActivity(), "Connect failed. Retry.", Toast.LENGTH_SHORT).show();
                Log.d(MultiImageSelectorFragment.TAG, ">>>>>>>>>>>>>>>>>>>>>!!Failed connection, rasoncode:"+reason+" !<<<<<<<<<<<");
            }
        });

}

Solution

  • That's correct, after the connection to the first device it will fail to connect with busy error code. The reason is that the WiFiP2P at your device didn't finish yet the first device connection process (even though you've accepted the connection and it got established, it still takes some time to create the group and release the resources).

    To overcome this issue, you can start another thread with some delay (from my tests at least 10-15 seconds) to attempt to connect to the second device.

    Goodluck.