WiFi P2P PEERS_CHANGED_ACTION未触发,无法发现对等设备求助
WiFi P2P无法发现对等设备的排查与修复方案
我来帮你搞定这个WiFi P2P找不到对等设备的问题,先拆解你代码里的关键问题,再一步步给你修复方案:
一、代码里的核心时序bug
在你的WiFiDirectBroadcastReceiver处理WIFI_P2P_PEERS_CHANGED_ACTION的时候,犯了一个异步操作的时序错误:你在调用mManager.requestPeers()之后立刻去判断mPeers.size() == 0,但requestPeers是异步方法,onPeersAvailable回调要等系统返回结果才会执行,这时候mPeers还没被填充数据,所以这个判断完全无效,会错误地输出“没有设备”。
修复方法:把空列表的判断移到onPeersAvailable回调内部,这样才能拿到真实的扫描结果。
二、缺失必要权限与位置服务要求
WiFi P2P的设备发现有严格的权限和系统要求,你大概率没配置全:
1. 必须添加的Manifest权限
在AndroidManifest.xml里加上这些权限:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- 声明支持WiFi P2P --> <uses-feature android:name="android.hardware.wifi.direct" android:required="true" />
2. 动态申请位置权限(Android 6.0+)
从Android 6.0开始,位置权限需要动态申请,而且WiFi P2P必须依赖位置服务才能扫描设备。在你的SelectPeerActivity里添加权限申请逻辑:
import android.Manifest; import android.content.pm.PackageManager; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; // ... 其他代码 ... private static final int REQUEST_LOCATION_PERM = 1001; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_select_peer); // ... 你的初始化代码(ListView、Adapter等) ... // 先检查位置权限,再启动扫描 checkLocationPermissionAndStartScan(); } private void checkLocationPermissionAndStartScan() { if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_LOCATION_PERM); } else { // 权限已获取,开始扫描 search(); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == REQUEST_LOCATION_PERM) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { search(); } else { Toast.makeText(this, "位置权限是WiFi P2P发现设备的必要条件,请开启权限", Toast.LENGTH_LONG).show(); } } }
三、修复BroadcastReceiver的Peer处理逻辑
修改WiFiDirectBroadcastReceiver中WIFI_P2P_PEERS_CHANGED_ACTION的代码,把空列表判断移到回调内部:
else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) { // 异步请求对等设备列表 if (mManager != null) { mManager.requestPeers(mChannel, new WifiP2pManager.PeerListListener() { @Override public void onPeersAvailable(WifiP2pDeviceList peerList) { mPeers = new ArrayList<>(peerList.getDeviceList()); // 更新UI显示设备列表 mActivity.displayPeers(peerList); // 在这里处理空列表情况 if (mPeers.isEmpty()) { Log.d("WiFiDirectDebug", "未发现任何对等设备"); Toast.makeText(mActivity, "附近没有可用的WiFi P2P设备", Toast.LENGTH_SHORT).show(); return; } // 生成连接配置列表 mConfigs = new ArrayList<>(); for (WifiP2pDevice peer : mPeers) { WifiP2pConfig config = new WifiP2pConfig(); config.deviceAddress = peer.deviceAddress; mConfigs.add(config); } } }); } }
四、额外排查要点
- 确保两台测试设备都开启了WiFi和WiFi Direct功能,并且位置服务处于开启状态
- 设备之间距离不要太远,WiFi P2P的有效传输距离一般在10米以内
- 部分设备需要关闭蓝牙、VPN等功能,避免干扰WiFi P2P扫描
- 在
discoverPeers的onFailure方法里,可以根据错误码定位问题:@Override public void onFailure(int reasonCode) { String errorMsg = ""; switch (reasonCode) { case WifiP2pManager.P2P_UNSUPPORTED: errorMsg = "当前设备不支持WiFi P2P"; break; case WifiP2pManager.BUSY: errorMsg = "系统正忙,请稍后重试"; break; case WifiP2pManager.ERROR: errorMsg = "WiFi P2P内部错误"; break; } Toast.makeText(SelectPeerActivity.this, "扫描失败:" + errorMsg, Toast.LENGTH_SHORT).show(); }
内容的提问来源于stack exchange,提问作者Neeraj Athalye
相关产品推荐
相关产品推荐

