So I did my homework and looked for similar questions, I actually found one person that had the same problem two years ago... he didn't get any answer though.
The problem is the following: I'm doing the WifiP2p tutorial from android. I call discoverPeers()
manually with this FloatingActionButton
on the MainActivity. Then WIFI_P2P_PEERS_CHANGED_ACTION
is broadcasted and received in the WifiDirectBroadcastReceiver class. There I call requestPeers()
, which in turn calls onPeersAvailable()
only if there is at least one discoverable peer (This makes perfect sense.)
The issue however is that once it has discovered a peer it will never go away from the list. Even if I shut down the detected device. Let me illustrate with an example:
- 3 Devices (A,B and C), all WiFi-Direct capable.
- Launch app on device A, keep the devices B and C shutdown.
- Try to detect with A, nothing gets detected. No problem.
- Turn on device B, go to WiFi-Direct settings, scan.
- Try to detect with A, detect B. No problem.
- Turn off device B.
- Try to detect with A, nothing gets detected. No problem.
- Turn on device C, go to WiFi-Direct settings, scan.
- Try to detect with A, detect C and B. But device B is still off. Why does it still get detected? (Worst, it gets detected with a status 3, which corresponds to AVAILABLE)
This happens with any permutation of the devices' roles. So the problem is really in the code since they all behave and detect normally with the official WiFi-Direct settings window.
Here is my MainActivity:
package com.gett.wifip2ptest;
import android.content.BroadcastReceiver;
import android.content.IntentFilter;
import android.net.wifi.p2p.WifiP2pDeviceList;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.content.Context;
import android.net.wifi.p2p.WifiP2pManager;
import android.net.wifi.p2p.WifiP2pManager.Channel;
import android.net.wifi.p2p.WifiP2pManager.PeerListListener;
import android.net.wifi.p2p.WifiP2pDevice;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity implements PeerListListener{
private WifiP2pManager mManager;
private Channel mChannel;
private BroadcastReceiver mReceiver;
private IntentFilter mIntentFilter;
private List<WifiP2pDevice> peers = new ArrayList<WifiP2pDevice>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
// If the discovery process succeeds and detects peers, the system broadcasts the
// WIFI_P2P_PEERS_CHANGED_ACTION intent.
mManager.discoverPeers(mChannel, new WifiP2pManager.ActionListener() {
@Override
public void onSuccess() {
Toast.makeText(MainActivity.this, "Discovery Initiated",
Toast.LENGTH_SHORT).show();
}
@Override
public void onFailure(int reasonCode) {
Toast.makeText(MainActivity.this, "Discovery Failed : " + reasonCode,
Toast.LENGTH_SHORT).show();
}
});
}
});
mManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
mChannel = mManager.initialize(this, getMainLooper(), null);
mReceiver = new WiFiDirectBroadcastReceiver(mManager, mChannel, this);
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);
}
/* register the broadcast receiver with the intent values to be matched */
@Override
protected void onResume() {
super.onResume();
registerReceiver(mReceiver, mIntentFilter);
}
/* unregister the broadcast receiver */
@Override
protected void onPause() {
super.onPause();
unregisterReceiver(mReceiver);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.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();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* This function is called by requestPeers upon receiving the peers list.
* @param peerList
*/
@Override
public void onPeersAvailable(WifiP2pDeviceList peerList) {
peers.clear();
System.out.println("Peers cleared : " + peers);
peers.addAll(peerList.getDeviceList());
System.out.println("Peers : " + peers);
if (peers.size() == 0) {
System.out.println("No devices found");
return;
}
}
}
Here is WiFiDirectBroadCastReceiver:
package com.gett.wifip2ptest;
import android.content.BroadcastReceiver;
import android.net.wifi.p2p.WifiP2pManager;
import android.net.wifi.p2p.WifiP2pManager.Channel;
import android.net.wifi.p2p.WifiP2pManager.PeerListListener;
import android.content.Context;
import android.content.Intent;
public class WiFiDirectBroadcastReceiver extends BroadcastReceiver {
private WifiP2pManager mManager;
private Channel mChannel;
private MainActivity mActivity;
public WiFiDirectBroadcastReceiver(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 to see if Wi-Fi is enabled and notify appropriate activity
int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1);
if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) {
// Wifi P2P is enabled
System.out.println("Wifi Direct has been enabled.");
} else {
// Wi-Fi P2P is not enabled
System.out.println("Wifi Direct is NOT enabled.");
}
} else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {
// Call WifiP2pManager.requestPeers() to get a list of current peers
System.out.println("Peers changed.");
// 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()
if (mManager != null) {
mManager.requestPeers(mChannel, (PeerListListener) mActivity);
}
} else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {
// Respond to new connection or disconnections
} else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) {
// Respond to this device's wifi state changing
}
}
}
Here is an example of two peers being detected while one of them is turned off:
02-18 16:31:56.406 20833-20833/com.gett.wifip2ptest I/System.out: Peers : [Device: Galaxy J1-2
02-18 16:31:56.406 20833-20833/com.gett.wifip2ptest I/System.out: deviceAddress: 2a:27:bf:3a:2e:55
02-18 16:31:56.406 20833-20833/com.gett.wifip2ptest I/System.out: primary type: 10-0050F204-5
02-18 16:31:56.406 20833-20833/com.gett.wifip2ptest I/System.out: secondary type: null
02-18 16:31:56.406 20833-20833/com.gett.wifip2ptest I/System.out: wps: 392
02-18 16:31:56.406 20833-20833/com.gett.wifip2ptest I/System.out: grpcapab: 0
02-18 16:31:56.406 20833-20833/com.gett.wifip2ptest I/System.out: devcapab: 37
02-18 16:31:56.406 20833-20833/com.gett.wifip2ptest I/System.out: status: 3
02-18 16:31:56.406 20833-20833/com.gett.wifip2ptest I/System.out: wfdInfo: null
02-18 16:31:56.406 20833-20833/com.gett.wifip2ptest I/System.out: groupownerAddress: null
02-18 16:31:56.406 20833-20833/com.gett.wifip2ptest I/System.out: GOdeviceName: null
02-18 16:31:56.406 20833-20833/com.gett.wifip2ptest I/System.out: interfaceAddress:
02-18 16:31:56.406 20833-20833/com.gett.wifip2ptest I/System.out: SConnectInfo : null, Device: Test User (Galaxy J1)
02-18 16:31:56.406 20833-20833/com.gett.wifip2ptest I/System.out: deviceAddress: 2a:27:bf:3a:4a:8b
02-18 16:31:56.406 20833-20833/com.gett.wifip2ptest I/System.out: primary type: 10-0050F204-5
02-18 16:31:56.406 20833-20833/com.gett.wifip2ptest I/System.out: secondary type: null
02-18 16:31:56.406 20833-20833/com.gett.wifip2ptest I/System.out: wps: 392
02-18 16:31:56.406 20833-20833/com.gett.wifip2ptest I/System.out: grpcapab: 0
02-18 16:31:56.406 20833-20833/com.gett.wifip2ptest I/System.out: devcapab: 37
02-18 16:31:56.406 20833-20833/com.gett.wifip2ptest I/System.out: status: 3
02-18 16:31:56.406 20833-20833/com.gett.wifip2ptest I/System.out: wfdInfo: null
02-18 16:31:56.406 20833-20833/com.gett.wifip2ptest I/System.out: groupownerAddress: null
02-18 16:31:56.406 20833-20833/com.gett.wifip2ptest I/System.out: GOdeviceName: null
02-18 16:31:56.406 20833-20833/com.gett.wifip2ptest I/System.out: interfaceAddress:
02-18 16:31:56.406 20833-20833/com.gett.wifip2ptest I/System.out: SConnectInfo : null]