androidandroid-wifiwifi-directwifimanagerwifip2p

WiFi P2P causes device WiFi auto-connect feature not to work?


I have an issue where my devices stops auto-connecting to WiFi networks when in range. My application has a service that runs in the background (even when the app is killed) that registers and unregisters a service every minute to repeatedly detect nearby devices using WiFi P2P.

 private final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) {
                int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1);
                if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) {
                    Log.d(TAG, "WiFi P2P Enabled");
                    if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                        return;
                    }
                    manager.discoverPeers(channel, new WifiP2pManager.ActionListener() {
                        @Override
                        public void onSuccess() {
                            Log.d(TAG, "Discover Peers Successful");
                        }

                        @Override
                        public void onFailure(int i) {
                            Log.d(TAG, "Discover Peers Unsuccessful");
                        }
                    });
                } else {
                    Log.d(TAG, "WiFi P2P Disabled");
                }
                // Check to see if Wi-Fi is enabled and notify appropriate activity
            } else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {
                Log.d(TAG, "Peers detected");
                if (manager != null) {
                    if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                        return;
                    }
                    Log.d(TAG, "Peers Requested");
                    manager.requestPeers(channel, peerListListener);
                }
                // Call WifiP2pManager.requestPeers() to get a list of current peers
            } else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {
                Log.d(TAG, "Connection Changed");
                // Respond to new connection or disconnections
            } else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) {
                Log.d(TAG, "WiFi P2P State Changed");
                // Respond to this device's wifi state changing
            }
        }
    };

 WifiP2pManager.PeerListListener peerListListener = new WifiP2pManager.PeerListListener() {
        @Override
        public void onPeersAvailable(WifiP2pDeviceList wifiP2pDeviceList) {
            Log.d(TAG, "Peers available");
            String deviceEncrypt = "";

            if (!wifiP2pDeviceList.getDeviceList().equals(peers)) {
                peers.clear();
                peers.addAll(wifiP2pDeviceList.getDeviceList());

                deviceNameArray = new String[wifiP2pDeviceList.getDeviceList().size()];
                deviceArray = new WifiP2pDevice[wifiP2pDeviceList.getDeviceList().size()];
                int index = 0;

                for (WifiP2pDevice device : wifiP2pDeviceList.getDeviceList()) {
                    deviceNameArray[index] = device.deviceName;
                    deviceArray[index] = device;
                    index++;

                    try {
                        deviceEncrypt = AESUtils.encrypt(device.deviceAddress);
                        Log.d(TAG, "Encrypted MAC Address discovered: " + deviceEncrypt);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            } else {
                Log.d(TAG, "No peers found");
            }
        }
    };

I realized that this is preventing the device from auto-connecting to known WiFi networks when in range. Any idea how to fix this? The code below registers and unregisters the broadcastReceiver every minute to achieve consistent peer detection (this is running in the onStartCommand function).

private void refreshTime() {
        handler.postDelayed(runnable = new Runnable() {
            @Override
            public void run() {
                Log.d(TAG, "Refreshed");
                registerReceiver(broadcastReceiver, intentFilter);
                unregisterReceiver(broadcastReceiver);
                registerReceiver(broadcastReceiver, intentFilter);
                handler.postDelayed(runnable, delay);
            }
        }, delay);
    }

Solution

  • Answering my own question. So manager.discoverPeers is what's preventing Android from auto-connecting to known Wifi networks. I fixed this by splitting refreshTime() to two different functions.

    private void refreshTime() {
            refreshHandler.postDelayed(refreshRunnable = new Runnable() {
                @Override
                public void run() {
                    Log.d(TAG, "Refreshed Registered");
                    registerReceiver(broadcastReceiver, intentFilter);
                    refreshHandler.postDelayed(refreshRunnable, refreshDelay);
                }
            }, refreshDelay);
        }
    
    private void stopDiscovery() {
            peerHandler.postDelayed(peerRunnable = new Runnable() {
                @Override
                public void run() {
                    manager.stopPeerDiscovery(channel, new WifiP2pManager.ActionListener() {
                        @Override
                        public void onSuccess() {
                            Log.d(TAG, "Peer Discovery Stopped");
                            try {
                                unregisterReceiver(broadcastReceiver);
                                Log.d(TAG, "Refreshed Unregistered");
                            } catch (IllegalArgumentException e) {
                                Log.e(TAG, e.toString());
                            }
                        }
    
                        @Override
                        public void onFailure(int i) {
                            Log.d(TAG, "Peer Discovery Failed to Stop");
                        }
                    });
                    peerHandler.postDelayed(peerRunnable, peerDelay);
                }
            }, peerDelay);
        }
    

    stopDiscovery() calls the manager.stopPeerDiscovery() and onSuccess it would unregister the broadcastReceiver.

    Both are running in two different intervals. refreshTime() runs every 1 minute while stopDiscovery() every 2 minutes. This stops the discoverPeers() for about a minute and allows the OS to auto-connect to known Wifi networks.

    Again. If anyone has a more elegant method to this, please share it with me. Thanks.