0

I am working on a wifi p2p file sharing application. But I am not able to discover the peers

Below is the code for my activity

    package com.neeraj8le.majorproject.activity;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.IntentFilter;
import android.net.wifi.p2p.WifiP2pDevice;
import android.net.wifi.p2p.WifiP2pDeviceList;
import android.net.wifi.p2p.WifiP2pManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

import com.neeraj8le.majorproject.R;
import com.neeraj8le.majorproject.WiFiDirectBroadcastReceiver;

import java.util.ArrayList;
import java.util.List;

public class SelectPeerActivity extends AppCompatActivity{

    WifiP2pManager mManager;
    WifiP2pManager.Channel mChannel;
    BroadcastReceiver mReceiver;
    IntentFilter mIntentFilter;
    ArrayAdapter<String> wifiP2pArrayAdapter;
    ListView listView;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_select_peer);

        listView = findViewById(R.id.list_view);

        wifiP2pArrayAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1);
        listView.setAdapter(wifiP2pArrayAdapter);

        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);

        mManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
        mChannel = mManager.initialize(this, getMainLooper(), null);
        mReceiver = new WiFiDirectBroadcastReceiver(mManager, mChannel, this);



        search();


    }

    public void search()
    {
        mManager.discoverPeers(mChannel, new WifiP2pManager.ActionListener() {
            @Override
            public void onSuccess() {
                Toast.makeText(SelectPeerActivity.this, "SUCCESS", Toast.LENGTH_SHORT).show();

            }

            @Override
            public void onFailure(int reasonCode) {
                Toast.makeText(SelectPeerActivity.this, "FAILURE", Toast.LENGTH_SHORT).show();
            }
        });

    }

    public void displayPeers(WifiP2pDeviceList peerList)
    {
        wifiP2pArrayAdapter.clear();

        for(WifiP2pDevice peer : peerList.getDeviceList())
            wifiP2pArrayAdapter.add(peer.deviceName + "\n" + peer.deviceAddress);

    }


    /* 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);
    }

}

And here is the code for my broadcastreceiver

package com.neeraj8le.majorproject;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.NetworkInfo;
import android.net.wifi.p2p.WifiP2pConfig;
import android.net.wifi.p2p.WifiP2pDevice;
import android.net.wifi.p2p.WifiP2pDeviceList;
import android.net.wifi.p2p.WifiP2pManager;
import android.util.Log;
import android.widget.Toast;

import com.neeraj8le.majorproject.activity.SelectPeerActivity;

import java.util.ArrayList;
import java.util.List;


public class WiFiDirectBroadcastReceiver extends BroadcastReceiver {

    private static final String TAG = ":::::::::::::::::::::";
    private WifiP2pManager mManager;
    private WifiP2pManager.Channel mChannel;
    private SelectPeerActivity mActivity;
    List<WifiP2pDevice> mPeers;
    List<WifiP2pConfig> mConfigs;

    public WiFiDirectBroadcastReceiver(WifiP2pManager manager, WifiP2pManager.Channel channel, SelectPeerActivity 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) {
                Toast.makeText(mActivity, "Wifi Direct Enabled", Toast.LENGTH_SHORT).show();
                // Wifi P2P is enabled
            } else {
                Toast.makeText(mActivity, "Wifi Direct Disabled", Toast.LENGTH_SHORT).show();
                // Wi-Fi P2P is not enabled
            }

        }
        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()
            mPeers = new ArrayList<>();
            mConfigs = new ArrayList<>();

            if (mManager != null) {

                mManager.requestPeers(mChannel, new WifiP2pManager.PeerListListener() {
                            @Override
                            public void onPeersAvailable(WifiP2pDeviceList peerList) {
                                mPeers.clear();
                                mPeers.addAll(peerList.getDeviceList());
                                mActivity.displayPeers(peerList);

                                for (int i = 0; i < peerList.getDeviceList().size(); i++) {
                                    WifiP2pConfig config = new WifiP2pConfig();
                                    config.deviceAddress = mPeers.get(i).deviceAddress;
                                    mConfigs.add(config);
                                }
                            }

                        });

            }

            if (mPeers.size() == 0) {
                Log.d("::::::::::::::::::::::", "No devices found");
                return;
            }

        }
        else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {
            Log.d(TAG, "wifi p2p connection changed action");
            NetworkInfo networkInfo = intent.getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO);
            Log.d(TAG,"network info available");
            // Respond to new connection or disconnections
        } else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) {
            // Respond to this device's wifi state
            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");
        }
    }
}

I have gotten most of the code from here

I debugged the app and all 3 intent filters were triggered except for

WIFI_P2P_PEERS_CHANGED_ACTION

I tried keeping another android device near my phone to see if it detects peers and one time id did trigger the WIFI_P2P_PEERS_CHANGED_ACTION intent.. but then it said that the peerlist size is 0 and hence I am unable to find peer.

Any help with the issue is greatly appreciated.

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
Neeraj Athalye
  • 508
  • 5
  • 26

2 Answers2

0

I guess the problem is that the device you try to discover is not "discoverable". Analogically to Bluetooth discovery in WiFi P2P it also has to be enabled, unfortunately it does not happen explicitly like in BT. From my experience, in order to be able to discover the other device, you have to:

  1. Navigate to WiFi -> Settings -> Wi-Fi Direct (on Android 6.0 it may differ depending on version). Just staying in the menu will do the job.
  2. Start discovery process on the other device as well.

It is a little bit tricky, but I was not able to find any other solution. The docs for Android WifiP2p also say nothing about it. See my answer, where I did more explaining.

Jakub Licznerski
  • 1,008
  • 1
  • 17
  • 33
  • It did trigger peers changed intent once and that was when I had gone to settings and enabled WiFi direct. But even after that it said that there are 0 peers.. additionally how do I enable the other device's WiFi direct without going to settings? How do I add that in my app? – Neeraj Athalye Jan 17 '18 at 10:03
  • You have to call `requestPeers` in `ON_PEERS_CHANGED` as described [here](https://developer.android.com/guide/topics/connectivity/wifip2p.html#creating-br). I didn't notice earlier that you only refer to method parameter. You enable other devices WiFi direct by initiating discovery on it. Also the scan lasts for 30 seconds so you might take it to consideration – Jakub Licznerski Jan 17 '18 at 10:19
  • I have called `requestPeers` in `ON_PEERS_CHANGED` in my code. Also I meant that how can you enable the other device's wifi direct also through their app.. Is it done by calling `discoverPeers` on the other device? – Neeraj Athalye Jan 17 '18 at 10:23
  • Ok then. I will try it by installing my app on another device and invoking `discoverPeers` on both devices simultaneously – Neeraj Athalye Jan 17 '18 at 10:25
  • 1
    have a look at `if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action))` again.. the `requestPeers` call is made there and it is not commented – Neeraj Athalye Jan 17 '18 at 10:29
  • I ran my app on my friends phone(Xiaomi Redmi 4A) and on my phone(Oneplus 5) at the same time. His phone was able to detect my phone. But my phone is not detecting his phone. – Neeraj Athalye Jan 17 '18 at 10:53
  • what are the Android API versions for this devices? The technology is rather unstable, also the stack varies from device to device. Did you inspect a debug log? – Jakub Licznerski Jan 17 '18 at 20:01
  • I tested on 2 devices other than mine which ran Android marshmallow and Android nougat .. my device is running on Android Oreo.. as for your next question I don't know what exactly you mean by inspecting a debug log – Neeraj Athalye Jan 18 '18 at 03:19
  • Android Oreo (8.0) probably has some major issues with connectivity I've already encountered a few in Blutooth e.g. [this](https://stackoverflow.com/questions/48286314/ble-scan-on-android-8-0). I'm affraid that it the OS fault. Maybe report a bug [here](https://source.android.com/setup/report-bugs) – Jakub Licznerski Jan 18 '18 at 03:26
  • Is there any other way of doing this without enabling anything on the other device ? Nearby sharing is enabled already, and If I try to share anything from device 1 to device 2 , on device 2 if the screen lock is unlocked, that's enough . – yasin tavukcuoglu Aug 20 '23 at 19:57
-1

to be able to detect other devices through direct Wi-Fi, you must have the location on each phone activated.