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

Android Wifi-Direct刷新按钮触发discoverPeers始终进入onFailure问题

解决Wifi-Direct discoverPeers失败的问题

1. 补充必要权限

Wifi-Direct运行需要多组权限支持,先在AndroidManifest.xml中添加以下配置:

<!-- 基础Wifi控制权限 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<!-- 定位权限(Android 6+强制要求,Wifi-Direct扫描依赖定位服务) -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- Android 12+蓝牙权限(Wifi-Direct设备发现依赖蓝牙) -->
<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<!-- 声明设备支持Wifi-Direct -->
<uses-feature android:name="android.hardware.wifi.direct" android:required="true" />

同时在代码中添加动态权限申请逻辑(适配Android 6及以上版本):

private static final int PERMISSIONS_REQUEST_CODE = 1001;
private String[] requiredPermissions = {
    Manifest.permission.ACCESS_FINE_LOCATION,
    Manifest.permission.CHANGE_WIFI_STATE,
    Manifest.permission.BLUETOOTH_SCAN
};

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

    // 先检查并申请必要权限
    if (!hasAllPermissions()) {
        requestPermissions(requiredPermissions, PERMISSIONS_REQUEST_CODE);
    }

    // 原有的初始化代码...
}

// 检查是否所有权限已授予
private boolean hasAllPermissions() {
    for (String perm : requiredPermissions) {
        if (ContextCompat.checkSelfPermission(this, perm) != PackageManager.PERMISSION_GRANTED) {
            return false;
        }
    }
    return true;
}

// 权限申请结果回调
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == PERMISSIONS_REQUEST_CODE) {
        boolean allGranted = true;
        for (int result : grantResults) {
            if (result != PackageManager.PERMISSION_GRANTED) {
                allGranted = false;
                break;
            }
        }
        if (!allGranted) {
            Toast.makeText(this, "需要授予所有权限才能使用Wifi-Direct功能", Toast.LENGTH_LONG).show();
            finish();
        }
    }
}

2. 修复Channel初始化与状态监听

初始化WifiP2pManager.Channel时,不要传入null作为ChannelListener,添加通道断开监听以便及时重建:

mWifiP2pChannel = mWifiP2pManager.initialize(this, getMainLooper(), new WifiP2pManager.ChannelListener() {
    @Override
    public void onChannelDisconnected() {
        // 通道断开时重新初始化
        mWifiP2pChannel = mWifiP2pManager.initialize(wifiLoginScreen.this, getMainLooper(), this);
        Toast.makeText(wifiLoginScreen.this, "Wifi-Direct通道已断开,正在重连", Toast.LENGTH_SHORT).show();
    }
});

3. 避免重复注册广播接收器

当前代码在onCreate和onResume重复注册广播接收器,会导致系统异常,修改为仅在onResume注册、onPause注销,并添加注册状态标记:

private boolean isReceiverRegistered = false;

@Override
protected void onResume() {
    super.onResume();
    if (!isReceiverRegistered) {
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
        intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
        registerReceiver(mReceiver, intentFilter);
        isReceiverRegistered = true;
    }
}

@Override
protected void onPause() {
    super.onPause();
    if (isReceiverRegistered) {
        unregisterReceiver(mReceiver);
        isReceiverRegistered = false;
    }
}

同时删除onCreate中的registerReceiver代码。

4. 优化discoverPeers调用逻辑

  • 增加防抖机制,避免短时间内重复触发搜索;
  • 在失败回调中根据错误码返回具体提示,方便排查问题:
private long lastDiscoverTime = 0;
private static final long DISCOVER_DELAY = 5000; // 5秒冷却时间

refreshButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        long currentTime = System.currentTimeMillis();
        if (currentTime - lastDiscoverTime < DISCOVER_DELAY) {
            Toast.makeText(wifiLoginScreen.this, "请稍后再尝试搜索", Toast.LENGTH_SHORT).show();
            return;
        }
        lastDiscoverTime = currentTime;

        if (mWifiDirectEnabled) {
            mWifiP2pManager.discoverPeers(mWifiP2pChannel, new WifiP2pManager.ActionListener() {
                @Override
                public void onSuccess() {
                    Toast.makeText(wifiLoginScreen.this, "正在搜索可用设备...", Toast.LENGTH_SHORT).show();
                }

                @Override
                public void onFailure(int reason) {
                    String errorMsg;
                    switch (reason) {
                        case WifiP2pManager.P2P_UNSUPPORTED:
                            errorMsg = "当前设备不支持Wifi-Direct";
                            break;
                        case WifiP2pManager.BUSY:
                            errorMsg = "系统正忙,请稍后再试";
                            break;
                        case WifiP2pManager.ERROR:
                            errorMsg = "搜索失败:系统内部错误";
                            break;
                        default:
                            errorMsg = "搜索失败,未知原因";
                    }
                    Toast.makeText(wifiLoginScreen.this, errorMsg, Toast.LENGTH_SHORT).show();
                }
            });
        } else {
            Toast.makeText(wifiLoginScreen.this, "Wifi-Direct未启用", Toast.LENGTH_SHORT).show();
        }
    }
});

5. 修正设备过滤逻辑(可选)

当前代码用device.deviceName.contains(ssid)过滤设备,但Wifi-Direct的设备名称不一定包含当前连接的SSID,这会导致即使发现设备也无法显示。建议先注释过滤逻辑,测试是否能正常获取设备列表,再根据需求调整:

@Override
public void onPeersAvailable(WifiP2pDeviceList peers) {
    mPeersList.clear();
    for (WifiP2pDevice device : peers.getDeviceList()) {
        // 先注释过滤逻辑,测试设备发现功能
        // if (device.deviceName.contains(ssid)) {
            mPeersList.add(device.deviceName + " (" + device.deviceAddress + ")");
        // }
    }
    mPeersAdapter.notifyDataSetChanged();
}

6. 设备环境检查

  • 确保设备已开启Wifi(Wifi-Direct依赖Wifi硬件,但无需连接热点);
  • 关闭省电模式(部分设备会在省电模式下禁用Wifi-Direct);
  • 确保两台设备距离在Wifi信号覆盖范围内;
  • 部分设备需开启蓝牙才能使用Wifi-Direct,检查蓝牙状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 23:42:14