gregoiregentil
gregoiregentil

Reputation: 1899

How to bindProcessToNetwork for a Wi-Fi P2P network?

I'm using Wi-Fi P2P network on Android in order to connect to an IoT device. The connection is established all the time. The device runs a DHCP server:

private class WiFiDirectBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
    String action = intent.getAction();
    if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {
    NetworkInfo networkInfo = intent.getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO);
    PRINTF("WiFiDirect WIFI_P2P_CONNECTION_CHANGED_ACTION " + networkInfo.getState());
    if (networkInfo.getState() == NetworkInfo.State.CONNECTED) {
        mManager.requestConnectionInfo(mChannel, new WifiP2pManager.ConnectionInfoListener() {
            @Override
            public void onConnectionInfoAvailable(WifiP2pInfo info) {
                //This function is reached. The device can be pinged to
                //info.groupOwnerAddress.getHostAddress()
            }
        });
    }
}

I would like to bind the process to this P2P network. I have added a network register callback which is called in case of Hotspot (without the P2P capability) but it's never being called for Wi-Fi P2P:

NetworkRequest nr = new NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.addCapability(NetworkCapabilities.NET_CAPABILITY_WIFI_P2P).build();
mConnectivityManager.registerNetworkCallback(nr, new ConnectivityManager.NetworkCallback() {
    @Override
    public void onAvailable(Network network) {
        super.onAvailable(network);
        //This is never being called for P2P
        mConnectivityManager.bindProcessToNetwork(network);
    }
});

Am I missing something?

Otherwise, how could I manage to "go up" and retrieve Network from NetworkInfo in WiFiDirectBroadcastReceiver?

Upvotes: 0

Views: 42

Answers (1)

Always Learning
Always Learning

Reputation: 2743

NetworkRequest.Builder will come with a default set of NetworkCapabilities link. What is most likely happening, is one of these capabilities is causing your NetworkRequest being passed into mConnectivityManager.registerNetworkCallback to not match your intended network.

My suggestion would two fold; first clear all the default capabilities using NetworkRequest.Builder#clearCapabilities() link:

Completely clears all the NetworkCapabilities from this builder instance, removing even the capabilities that are set by default when the object is constructed. Also removes any set forbidden capabilities.

Second, only pass in the capabilities you actually need (e.g., no need to pass in the transport type in your case) to the NetworkRequest.Builder object:

NetworkRequest nr = new NetworkRequest.Builder()
.clearCapabilities()
.addCapability(NetworkCapabilities.NET_CAPABILITY_WIFI_P2P).build();
mConnectivityManager.registerNetworkCallback(nr, new ConnectivityManager.NetworkCallback() {
    @Override
    public void onAvailable(Network network) {
        super.onAvailable(network);
        //This should hopefully be called now.
        mConnectivityManager.bindProcessToNetwork(network);
    }
});

In the future, if you ever have more than one Wi-Fi P2P network, you can always use a NetworkSpecifier link to choose between them.

Lastly, you can use adb shell dumpsys connectivity | grep -i NetworkAgentInfo to list the currently available networks (such as your Wi-Fi P2P network). You can see the network capabilities of those networks in the nc object. You can manually expect those capabilities and make sure your NetworkRequest would be "satisfied" by that network's capabilities. E.g., if you pass in a request with the capability INTERNET, and the network you are interested in doesn't have that capability, than it won't ever be chosen as it doesn't satisfy your NetworkRequest.

Upvotes: 1

Related Questions