title: Android wifi p2p peers visibility
body: <p>I'm trying to connect 2 devices with wifi direct, let's say device A and device B with android > 4.1. If I'm on device A and I press the button to search for other devices it doesn't act always the same way. </p>
  
  <p>For example if I press the search button on device A, it doesn't find anything until I press the search button on the device B too, even if the app is going on both. <strong>So the device B is not visible until it doesn't start searching for other devices too</strong>. </p>
  
  <p>Other times if I search for devices with device A, it finds device B even if the app was closed recently on device B and if I try to connect to device B it works. <strong>The problem is that I want to establish a connection only if the app is running on both devices</strong>.</p>
  
  <p>Sometimes when device A finds out device B and it tries to connect to it, it doesn't work until device B starts to find devices. <strong>So when I start the searching on device B it receives the connection request from A, but nothing until then.</strong></p>
  
  <p>Some other times, after pressing the search button on device A, <strong>it shows some devices that hasn't the wifi enabled at that moment or that are out of range</strong>.</p>
  
  <p>Here's my code:</p>
  
  <p>MainActivity.java </p>
  
  <pre><code>import java.lang.reflect.Method;
  import java.util.ArrayList;
  import java.util.List;
  
  import android.app.Activity;
  import android.content.BroadcastReceiver;
  import android.content.Context;
  import android.content.IntentFilter;
  import android.net.wifi.WpsInfo;
  import android.net.wifi.p2p.WifiP2pConfig;
  import android.net.wifi.p2p.WifiP2pDevice;
  import android.net.wifi.p2p.WifiP2pDeviceList;
  import android.net.wifi.p2p.WifiP2pGroup;
  import android.net.wifi.p2p.WifiP2pManager;
  import android.net.wifi.p2p.WifiP2pManager.ActionListener;
  import android.net.wifi.p2p.WifiP2pManager.Channel;
  import android.net.wifi.p2p.WifiP2pManager.GroupInfoListener;
  import android.net.wifi.p2p.WifiP2pManager.PeerListListener;
  import android.os.Bundle;
  import android.view.Menu;
  import android.view.MenuItem;
  import android.view.View;
  import android.view.View.OnClickListener;
  import android.widget.AdapterView;
  import android.widget.AdapterView.OnItemClickListener;
  import android.widget.ArrayAdapter;
  import android.widget.Button;
  import android.widget.CheckedTextView;
  import android.widget.ListView;
  import android.widget.Toast;
  
  
  public class MainActivity extends Activity implements OnItemClickListener, PeerListListener {
  
      private WifiP2pManager mManager;
      private Channel mChannel;
      private BroadcastReceiver mReceiver;
      private IntentFilter mIntentFilter;
      private List&lt;WifiP2pDevice&gt; peers = new ArrayList&lt;WifiP2pDevice&gt;();
      private List&lt;WifiP2pDevice&gt; peersConnect = new ArrayList&lt;WifiP2pDevice&gt;();
      private ArrayList&lt;String&gt; peersName = new ArrayList&lt;String&gt;();
      private ListView list;
      private Button bSearch;
      private Button bConnect;
      private Button bDisconnect;
      private int nSelectedDevices = 0;
  
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
          mManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
          mChannel = mManager.initialize(this, getMainLooper(), null);
  
          try {
              Class&lt;?&gt; wifiManager = Class
                      .forName("android.net.wifi.p2p.WifiP2pManager");
  
              Method method = wifiManager
                      .getMethod(
                              "enableP2p",
                              new Class[] { android.net.wifi.p2p.WifiP2pManager.Channel.class });
  
              method.invoke(mManager, mChannel);
  
          } catch (Exception e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
          }
  
  
          mIntentFilter = new IntentFilter();
          mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
          mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
          mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
          mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
          mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION);
  
          bSearch = (Button) this.findViewById(R.id.searcher);
          bSearch.setOnClickListener(new OnClickListener() {
              public void onClick (View v) {
                  list.setVisibility(ListView.INVISIBLE);
                  bConnect.setVisibility(View.INVISIBLE);
                  bDisconnect.setVisibility(View.INVISIBLE);
                  nSelectedDevices = 0;
                  peersConnect.clear();
                  peers.clear();
                  peersName.clear();
                  searchDevices();        
              }
          });
  
          bConnect = (Button) this.findViewById(R.id.connecter);
          bConnect.setOnClickListener(new OnClickListener() {
              public void onClick (View v) {
                  bDisconnect.setVisibility(View.VISIBLE);
                  connectDevices();       
                  bConnect.setVisibility(View.INVISIBLE);
                  nSelectedDevices = 0;
                  peersConnect.clear();
              }
          });
  
          bDisconnect = (Button) this.findViewById(R.id.disconnecter);
          bDisconnect.setOnClickListener(new OnClickListener() {
              public void onClick (View v) {
                  disconnectDevices();
                  peersConnect.clear();
                  bDisconnect.setVisibility(View.INVISIBLE);
              }
          });
  
          list = (ListView) this.findViewById(R.id.list);
          list.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
           //--   text filtering
          list.setTextFilterEnabled(true);
  
  
      }
  
      /* register the broadcast receiver with the intent values to be matched */
      @Override
      protected void onResume() {
          super.onResume();
          mReceiver = new WifiReceiver(mManager, mChannel, this);
          registerReceiver(mReceiver, mIntentFilter);
      }
  
      /* unregister the broadcast receiver */
      @Override
      protected void onPause() {
          super.onPause();
          unregisterReceiver(mReceiver);
      }
  
      @Override
      protected void onDestroy() {
          super.onDestroy();
          finish();
      }
  
  
  
      public void onItemClick(AdapterView&lt;?&gt; parent, View v, int position, long id) {
          CheckedTextView item = (CheckedTextView) v;
          if(item.isChecked()) {
              nSelectedDevices++;
              peersConnect.add(peers.get(position));
          }
          else {
              nSelectedDevices--;
              peersConnect.remove(peers.get(position));
          }
          if(nSelectedDevices == 1)
              bConnect.setVisibility(View.VISIBLE);
          else if(nSelectedDevices == 0)
              bConnect.setVisibility(View.INVISIBLE);
      }
  
      @Override
      public void onPeersAvailable(WifiP2pDeviceList peerList) {
  
          // Out with the old, in with the new.
          peers.clear();
          peers.addAll(peerList.getDeviceList());
          getDeviceName();
          list.setAdapter(new ArrayAdapter&lt;String&gt;(this, android.R.layout.simple_list_item_checked, peersName));
          list.setOnItemClickListener(this);
          list.setVisibility(ListView.VISIBLE);
          // If an AdapterView is backed by this data, notify it
          // of the change.  For instance, if you have a ListView of available
          // peers, trigger an update.
          //((ListAdapter) getListAdapter()).notifyDataSetChanged();
          if (peers.size() == 0) {
              return;
          }
      }
  
      private void searchDevices() {
          mManager.discoverPeers(mChannel, new WifiP2pManager.ActionListener() {
              @Override
              public void onSuccess() {
                  //Toast.makeText(MainActivity.this, "Inizio ricerca...", Toast.LENGTH_SHORT).show();
              }
  
              @Override
              public void onFailure(int reasonCode) {
                  //Toast.makeText(MainActivity.this, "Ricerca fallita!", Toast.LENGTH_SHORT).show();
              }
          });
  
      }
  
      private void connectDevices() {
          for(int i = 0; i &lt; peersConnect.size(); i++) {
  
              // Picking the first device found on the network.
              WifiP2pDevice device = peersConnect.get(i);
  
              WifiP2pConfig config = new WifiP2pConfig();
              config.deviceAddress = device.deviceAddress;
              config.wps.setup = WpsInfo.PBC;
  
              mManager.connect(mChannel, config, new ActionListener() {
  
                  @Override
                  public void onSuccess() {
                      // WiFiDirectBroadcastReceiver will notify us. Ignore for now.
                      Toast.makeText(MainActivity.this, "Connection requested...", Toast.LENGTH_SHORT).show();
                  }
  
                  @Override
                  public void onFailure(int reason) {
                      Toast.makeText(MainActivity.this, "Connect failed. Retry.", Toast.LENGTH_SHORT).show();
                  }
              });
          }
      }
  
      public void disconnectDevices() {
          if (mManager != null &amp;&amp; mChannel != null) {
              mManager.requestGroupInfo(mChannel, new GroupInfoListener() {
                  @Override
                  public void onGroupInfoAvailable(WifiP2pGroup group) {
                      if (group != null &amp;&amp; mManager != null &amp;&amp; mChannel != null &amp;&amp; group.isGroupOwner()) {
                          mManager.removeGroup(mChannel, new ActionListener() {
                              @Override
                              public void onSuccess() {
  
                              }
  
                              @Override
                              public void onFailure(int reason) {
  
                              }
                          });
                      }
                  }
              });
          }
      }
  
  
      private void getDeviceName() {
          int i = 0;
          peersName.clear();
          while(i &lt; peers.size()) {
              peersName.add(peers.get(i).deviceName);
              i++;
          }
      }
  
      @Override
      public boolean onCreateOptionsMenu(Menu menu) {
          // Inflate the menu; this adds items to the action bar if it is present.
          getMenuInflater().inflate(R.menu.main, menu);
          return true;
      }
  
      @Override
      public boolean onOptionsItemSelected(MenuItem item) {
          // Handle action bar item clicks here. The action bar will
          // automatically handle clicks on the Home/Up button, so long
          // as you specify a parent activity in AndroidManifest.xml.
          int id = item.getItemId();
          if (id == R.id.action_settings) {
              return true;
          }
          return super.onOptionsItemSelected(item);
      }
  }
  </code></pre>
  
  <p>WifiReceiver.java</p>
  
  <pre><code>import android.content.BroadcastReceiver;
  import android.content.Context;
  import android.content.Intent;
  import android.net.wifi.p2p.WifiP2pManager;
  import android.net.wifi.p2p.WifiP2pManager.Channel;
  import android.widget.Toast;
  
  public class WifiReceiver extends BroadcastReceiver {
  
      private WifiP2pManager mManager;
      private Channel mChannel;
      private MainActivity mActivity;
  
      public WifiReceiver(WifiP2pManager manager, Channel channel, MainActivity activity) {
          super();
          this.mManager = manager;
          this.mChannel = channel;
          this.mActivity = activity;
      }
  
      @Override
      public void onReceive(Context context, Intent intent) {
          String action = intent.getAction();
  
          if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) { // check if wifi is enabled/disabled
              System.out.println("Connection changed");
              int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1);
              if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) {
                  //mActivity.setIsWifiP2pEnabled(true);
              } else {
                  //mActivity.setIsWifiP2pEnabled(false);
              }
          } else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {
              // Call WifiP2pManager.requestPeers() to get a list of current peers
              // request available peers from the wifi p2p manager. This is an
              // asynchronous call and the calling activity is notified with a
              // callback on PeerListListener.onPeersAvailable()
              System.out.println("Peers changed");
              if (mManager != null) {
                  mManager.requestPeers(mChannel, mActivity);
  
              }
          } else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {
              // Respond to new connection or disconnections
              System.out.println("Connection changed");
          } else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) {
              // Respond to this device's wifi state changing
              System.out.println("This device changed");
          }
          else if (WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION.equals(action)) {
              // Respond to this device's wifi state changing
              System.out.println("Search peers");
          }
      }
  
  }
  </code></pre>
  
  <p>activity_main.xml</p>
  
  <pre><code>&lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:tools="http://schemas.android.com/tools"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:orientation="horizontal" &gt;
  
      &lt;LinearLayout
          android:layout_width="match_parent"
          android:layout_height="wrap_content" 
          android:id="@+id/linearlayout1" &gt;
          &lt;Button
              android:id="@+id/searcher"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:text="@string/button_send" /&gt;
  
          &lt;Button
              android:id="@+id/connecter"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:text="@string/button_connect"
              android:visibility="invisible" /&gt;
  
          &lt;Button
              android:id="@+id/disconnecter"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:text="@string/button_disconnect"
              android:visibility="invisible" /&gt;
      &lt;/LinearLayout&gt;
  
      &lt;LinearLayout
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:layout_below="@+id/linearlayout1" &gt;
  
          &lt;ListView
              android:id="@+id/list"
              android:layout_width="match_parent"
              android:layout_height="380dp"
              android:layout_alignParentLeft="true"
              android:visibility="invisible" &gt;
          &lt;/ListView&gt;
      &lt;/LinearLayout&gt;
  "
  
  &lt;/RelativeLayout&gt;
  </code></pre>
  
  <p>I don't understand how works <code>mManager.discoverPeers()</code> and <code>mManager.requestPeers()</code>.</p>
  
  <p>Thank you for your attention!!</p>