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

WiFi Aware会话发现功能失效问题排查求助

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 00:04:58