Search code examples
androidconnectionbroadcastreceiverwifi-directwifip2p

Android WiFi Direct android.net.wifi.p2p.PEERS_CHANGED received endlessly


community, this is my first question, so please tell me if I accidentally don't match some norms or similiar.

I am trying to code an android application that communicates with WiFi direct. Everything works smooth at this point, but my BroadcastReceiver receives the android.net.wifi.p2p.PEERS_CHANGED action again and again.

public class WifiP2PBroadcastReceiver extends BroadcastReceiver {
private final static String TAG = "WifiP2PBR";
private WifiP2pManager _manager;
private WifiP2pManager.Channel _channel;
private Activity _callbackActivity;

private static ArrayList<WifiBroadcastCallback> _arrayList_callbacks;

public WifiP2PBroadcastReceiver(WifiP2pManager manager, WifiP2pManager.Channel channel, Activity callback) {
    _manager = manager;
    _channel = channel;
    _callbackActivity = callback;
}


/**
 * add a callback to the receiver
 *
 * @param callback
 */
public static void addWifiCallback(WifiBroadcastCallback callback) {
    if(!getCallbacksList().contains(callback))
    {
        getCallbacksList().add(callback);
    }
}

public void registerReceiver()
{
    Log.d(TAG,"registerReceiver called");
    if(_callbackActivity != null) {
        _callbackActivity.registerReceiver(this, getIntentFilter());
    }
}

public void unregisterReceiver() {
    if(_callbackActivity != null) {
        _callbackActivity.unregisterReceiver(this);
    }
}


@Override
public final void onReceive(Context context, Intent intent) {
    Log.d(TAG, "action: "+intent.getAction());
    switch(intent.getAction()) {
        case WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION:
            Log.d(TAG, "state changed action");
            break;
        case WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION:
            Log.d(TAG, "peers changed action");
            notifyPeerUpdate();
            break;
        case WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION:
            Log.d(TAG, "wifi p2p connection changed action");
            NetworkInfo networkInfo = intent.getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO);
            Log.d(TAG,"network info available");
            break;
        case WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION:
            Log.d(TAG, "wifi p2p this device changed action");
            notifyDeviceUpdate();
            WifiP2pDevice thisDevice = intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_DEVICE);
            Log.d(TAG,"this device acquired");
            break;
    }
}

private void notifyPeerUpdate()
{
    for(WifiBroadcastCallback c : getCallbacksList())
    {
        c.onPeersChanged();
    }
}

private void notifyDeviceUpdate()
{
    for(WifiBroadcastCallback c : getCallbacksList())
    {
        c.onDeviceChanged();
    }
}

/**
 * get array list of callbacks
 *
 * @return
 */
private static ArrayList<WifiBroadcastCallback> getCallbacksList() {
    if(_arrayList_callbacks == null) {
        _arrayList_callbacks = new ArrayList<WifiBroadcastCallback>();
    }
    return _arrayList_callbacks;
}

/**
 * interface for callbacks
 */
public interface WifiBroadcastCallback {
    void onDeviceChanged();

    void onPeersChanged();
}

private IntentFilter getIntentFilter()
{
    IntentFilter intentFilter = new IntentFilter();
    intentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
    intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
    intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
    intentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);

    return intentFilter;
}

}

this is my BroadcastReceiver code. Everything else works fine and I'm out of ideas, it started out of the nowhere.


Solution

  • That's how it works indeed. Basically, what you should do there, is to call requestPeers with your instance of WifiP2pManager. Then you onPeersAvailable from WifiP2pManager.PeerListListener would be called with the array of peers seen, and there you could then check whether the change is something that you want to report.

    reference implementation can be found from my github projects