You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Wi-Fi P2P网络调用bindProcessToNetwork绑定进程?

问题

我在Android平台使用Wi-Fi P2P网络连接IoT设备,连接已成功建立,该设备运行DHCP服务器,相关代码如下:

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

我希望将进程绑定到该P2P网络,已添加网络注册回调,该回调在普通热点场景下会触发,但在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);
    }
});

请问我是否遗漏了什么配置?或者,如何在WiFiDirectBroadcastReceiver中从NetworkInfo获取对应的Network对象?

解决方案

一、NetworkCallback未触发的修复方案

  1. 补全必要权限
    确保Manifest中声明以下权限,Wi-Fi P2P相关操作依赖这些权限:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />

其中ACCESS_FINE_LOCATION是Android 10及以上版本要求的,CHANGE_NETWORK_STATE用于进程绑定网络操作。

  1. 调整NetworkRequest配置
    部分设备的Wi-Fi P2P网络未正确标记NET_CAPABILITY_WIFI_P2P,可以尝试简化NetworkRequest的筛选条件:
NetworkRequest nr = new NetworkRequest.Builder()
    .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
    .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) // 部分设备需要这个标记
    .build();

如果还是不触发,可在连接成功后主动遍历所有网络查找目标P2P网络:

ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
Network[] networks = cm.getAllNetworks();
for (Network network : networks) {
    NetworkCapabilities capabilities = cm.getNetworkCapabilities(network);
    if (capabilities != null && capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
        // 匹配到Wi-Fi网络,进一步确认是否为P2P
        NetworkInfo ni = cm.getNetworkInfo(network);
        if (ni != null && ni.getType() == ConnectivityManager.TYPE_WIFI_P2P && ni.isConnected()) {
            cm.bindProcessToNetwork(network);
            break;
        }
    }
}

二、从NetworkInfo获取Network对象的方法

广播中的NetworkInfo无法直接拿到Network对象,但可以通过以下方式间接匹配:

  1. 在连接成功后遍历网络匹配
    在WIFI_P2P_CONNECTION_CHANGED_ACTION的连接分支中,通过ConnectivityManager查询所有网络,匹配Wi-Fi P2P类型:
if (networkInfo.getState() == NetworkInfo.State.CONNECTED) {
    ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    Network[] networks = cm.getAllNetworks();
    for (Network network : networks) {
        NetworkInfo ni = cm.getNetworkInfo(network);
        if (ni != null && ni.getType() == ConnectivityManager.TYPE_WIFI_P2P && ni.isConnected()) {
            cm.bindProcessToNetwork(network);
            break;
        }
    }
    // 保留原有的requestConnectionInfo逻辑
    mManager.requestConnectionInfo(mChannel, ...);
}
  1. 结合WifiP2pInfo的IP地址精准匹配
    如果存在多个Wi-Fi网络,可通过WifiP2pInfo中的组所有者IP地址,匹配网络的链路属性:
mManager.requestConnectionInfo(mChannel, new WifiP2pManager.ConnectionInfoListener() {
    @Override
    public void onConnectionInfoAvailable(WifiP2pInfo info) {
        String targetIp = info.groupOwnerAddress.getHostAddress();
        ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        Network[] networks = cm.getAllNetworks();
        for (Network network : networks) {
            LinkProperties lp = cm.getLinkProperties(network);
            if (lp != null) {
                for (LinkAddress la : lp.getLinkAddresses()) {
                    if (la.getAddress().getHostAddress().equals(targetIp)) {
                        cm.bindProcessToNetwork(network);
                        break;
                    }
                }
            }
        }
    }
});

三、额外提示

如果不需要绑定整个进程,仅需特定Socket使用P2P网络,可使用network.bindSocket(socket)方法,更灵活且避免影响其他网络请求。

内容的提问来源于stack exchange,提问作者gregoiregentil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 07:20:21