WiFi Aware会话发现功能失效问题排查求助
问题背景
我正在开发一款WiFi Aware应用,代码运行无异常,但在Google Pixel 8设备上发布会话后,另一台Pixel 8无法发现该服务。已通过谷歌官方测试应用验证硬件功能正常,核心发布与订阅代码如下:
public void publish(View view) { boolean hasWifiAware = getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_AWARE); logger.log(Level.INFO, "This device has WiFi-Aware: " + hasWifiAware); WifiAwareManager wifiAwareManager = (WifiAwareManager) getSystemService(Context.WIFI_AWARE_SERVICE); Handler handler = new Handler(); wifiAwareManager.attach(new PublishAttachCallback(), handler); } public void subscribe(View view) { boolean hasWifiAware = getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_AWARE); logger.log(Level.INFO, "This device has WiFi-Aware: " + hasWifiAware); WifiAwareManager wifiAwareManager = (WifiAwareManager) getSystemService(Context.WIFI_AWARE_SERVICE); Handler handler = new Handler(); wifiAwareManager.attach(new SubscribeAttachCallback(), handler); } class PublishAttachCallback extends AttachCallback { private Logger logger = Logger.getLogger("MainActivity"); @Override public void onAttachFailed() { logger.log(Level.ERROR, "Publish onAttacheFailed!"); } @Override public void onAttached(WifiAwareSession session) { Toast.makeText(MainActivity.this, "onAttach", Toast.LENGTH_SHORT).show(); MainActivity.this.mAwareSession = session; PublishConfig config = new PublishConfig.Builder() .setServiceName(AWARE_SERVICE_NAME) .build(); if (ActivityCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_CODE); } if(ActivityCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.NEARBY_WIFI_DEVICES) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.NEARBY_WIFI_DEVICES}, REQUEST_CODE); } MainActivity.this.mAwareSession.publish(config, new DiscoverySessionCallback() { @Override public void onPublishStarted(PublishDiscoverySession session) { logger.log(Level.INFO, "Publish started!"); Toast.makeText(MainActivity.this, "onPublishStarted", Toast.LENGTH_SHORT).show(); } @Override public void onMessageReceived(PeerHandle peerHandle, byte[] message) { logger.log(Level.INFO, "Message received"); Toast.makeText(MainActivity.this, "onMessageReceived : " + message.toString(), Toast.LENGTH_SHORT).show(); } }, null); } } class SubscribeAttachCallback extends AttachCallback { @Override public void onAttachFailed() { logger.log(Level.ERROR, "Subscribe onAttacheFailed!"); } @Override public void onAttached(WifiAwareSession session) { Toast.makeText(MainActivity.this, "onAttach", Toast.LENGTH_SHORT).show(); MainActivity.this.mAwareSession = session; SubscribeConfig config = new SubscribeConfig.Builder() .setServiceName(AWARE_SERVICE_NAME) .build(); if (ActivityCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_CODE); } if(ActivityCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.NEARBY_WIFI_DEVICES) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.NEARBY_WIFI_DEVICES}, REQUEST_CODE); } MainActivity.this.mAwareSession.subscribe(config, new DiscoverySessionCallback() { private PeerHandle mPeerHandle = null; @Override public void onServiceDiscovered(PeerHandle peerHandle, byte[] serviceSpecificInfo, List<byte[]> matchFilter){ Toast.makeText(MainActivity.this, "onServiceDiscovered!", Toast.LENGTH_SHORT).show(); mPeerHandle = peerHandle; if(mPeerHandle == null) { logger.log(Level.ERROR, "mPeerHandle is null!"); } } @Override public void onSubscribeStarted(SubscribeDiscoverySession session1) { Toast.makeText(MainActivity.this, "onSubscribeStarted", Toast.LENGTH_SHORT).show(); if (mPeerHandle != null) { int messageId = 1; session1.sendMessage(mPeerHandle, messageId, "Test Message".getBytes()); } else { Toast.makeText(MainActivity.this, "mPeerHandle is null in onSubscribeStarted!", Toast.LENGTH_SHORT).show(); } } @Override public void onMessageSendSucceeded(int messageId) { logger.log(Level.INFO, "Message send succeeded!"); Toast.makeText(MainActivity.this, "onMessageSendSucceeded for " + messageId, Toast.LENGTH_SHORT).show(); } @Override public void onMessageSendFailed(int messageId) { logger.log(Level.ERROR, "Message send failed!"); Toast.makeText(MainActivity.this, "onMessageSendFailed for " + messageId, Toast.LENGTH_SHORT).show(); } @Override public void onMessageReceived(PeerHandle peerHandle, byte[] message) { logger.log(Level.INFO, "Message received!"); } }, null); } }
核心问题与修复方案
1. 权限申请时机错误,导致发布/订阅静默失败
你在onAttached()回调中才检查并申请权限,但此时已经调用了publish()/subscribe()方法。当权限未授予时,这些操作会静默失败,不会触发错误回调,直接导致服务无法发布或订阅。
修复方式:
将权限检查逻辑前置到publish()/subscribe()方法的最开始,确保权限全部授予后再执行WiFi Aware的初始化流程:
public void publish(View view) { // 先检查权限 if (!checkAllPermissions()) { requestAllPermissions(); return; } boolean hasWifiAware = getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_AWARE); logger.log(Level.INFO, "This device has WiFi-Aware: " + hasWifiAware); WifiAwareManager wifiAwareManager = (WifiAwareManager) getSystemService(Context.WIFI_AWARE_SERVICE); Handler handler = new Handler(); wifiAwareManager.attach(new PublishAttachCallback(), handler); } // 封装权限检查方法 private boolean checkAllPermissions() { return ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.NEARBY_WIFI_DEVICES) == PackageManager.PERMISSION_GRANTED; } // 封装权限申请方法 private void requestAllPermissions() { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.NEARBY_WIFI_DEVICES}, REQUEST_CODE); }
2. 未处理权限申请结果,无法触发后续流程
当前代码仅发起权限申请,但未实现onRequestPermissionsResult()来处理用户的权限选择。如果用户授予权限,后续的WiFi Aware流程不会自动触发;如果用户拒绝,后续操作依然会失败。
修复方式:
重写onRequestPermissionsResult(),在权限通过后重新触发发布/订阅操作:
@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == REQUEST_CODE) { boolean allGranted = true; for (int result : grantResults) { if (result != PackageManager.PERMISSION_GRANTED) { allGranted = false; break; } } if (allGranted) { // 根据当前操作类型重新触发(可以用标记变量记录是发布还是订阅) // 例如:if (isPublishAction) publish(null); else subscribe(null); } else { Toast.makeText(this, "需要权限才能使用WiFi Aware功能", Toast.LENGTH_SHORT).show(); } } }
3. Subscribe端逻辑顺序错误,导致PeerHandle为空
SubscribeDiscoverySession的回调触发顺序是:onSubscribeStarted() → onServiceDiscovered(),你在onSubscribeStarted()中直接使用mPeerHandle必然为空,因为此时还未发现任何服务。
修复方式:
仅在onServiceDiscovered()回调收到有效的PeerHandle后,再执行发送消息的逻辑:
@Override public void onServiceDiscovered(PeerHandle peerHandle, byte[] serviceSpecificInfo, List<byte[]> matchFilter){ Toast.makeText(MainActivity.this, "onServiceDiscovered!", Toast.LENGTH_SHORT).show(); mPeerHandle = peerHandle; if(mPeerHandle != null) { // 发现服务后立即发送消息 int messageId = 1; session1.sendMessage(mPeerHandle, messageId, "Test Message".getBytes()); } else { logger.log(Level.ERROR, "mPeerHandle is null!"); } } @Override public void onSubscribeStarted(SubscribeDiscoverySession session1) { Toast.makeText(MainActivity.this, "onSubscribeStarted", Toast.LENGTH_SHORT).show(); // 此处不再尝试发送消息,等待onServiceDiscovered回调 }
4. 可选优化:显式配置发布/订阅类型
部分设备可能需要显式指定发布/订阅类型才能正常发现服务,可以尝试添加以下配置:
- 发布端:
PublishConfig config = new PublishConfig.Builder() .setServiceName(AWARE_SERVICE_NAME) .setPublishType(PublishConfig.PUBLISH_TYPE_UNSOLICITED) // 主动广播服务 .build();
- 订阅端:
SubscribeConfig config = new SubscribeConfig.Builder() .setServiceName(AWARE_SERVICE_NAME) .setSubscribeType(SubscribeConfig.SUBSCRIBE_TYPE_PASSIVE) // 被动监听服务 .build();
内容的提问来源于stack exchange,提问作者sikienzl

