【问题标题】:Android WiFi-Direct: discovering, connecting issues. Detailed discussionAndroid WiFi-Direct:发现、连接问题。详细讨论
【发布时间】:2016-07-09 18:31:48
【问题描述】:

我正在开发一个应用程序,它使用 wifi-direct 创建最多 4 个设备的组(1 个主机 + 3 个对等设备)。我从 developer.android.com 阅读了 wifi-direct 手册,找到了这个绝妙的答案:https://stackoverflow.com/a/31641302/3106249 - 不过,我还有几个问题我不知道如何处理。

第一个问题一步一步:

  1. 注册本地服务并在主机设备上创建组。

    Map<String, String> record = new HashMap<String, String>();
    record.put(TXTRECORD_PROP_AVAILABLE, "visible");
    record.put(Core.SESSION_KEY, Core.SESSION_KEY_VALUE);
    record.put(Core.SERVICE_INSTANCE_KEY, SERVICE_INSTANCE);
    localService = WifiP2pDnsSdServiceInfo.newInstance(SERVICE_INSTANCE, Core.SERVICE_REG_TYPE, record);
    
    manager.clearLocalServices(channel, new WifiP2pManager.ActionListener() {
        @Override
        public void onSuccess() {
            Log.d(TAG, "clearLocalServices success");
    
            manager.addLocalService(channel, localService, new WifiP2pManager.ActionListener() {
                @Override
                public void onSuccess() {
                    Log.d(TAG, "addLocalService success");
    
                    manager.createGroup(channel, new WifiP2pManager.ActionListener() {
                        @Override
                        public void onSuccess() {
                            Log.d(TAG, "createGroup success");
                        }
    
                        @Override
                        public void onFailure(int reason) {
                            Log.d(TAG, "createGroup fail: " + reason);
                        }
                    });
                }
    
                @Override
                public void onFailure(int reason) {
                    Log.d(TAG, "addLocalService fail: " + reason);
                }
            });
        }
    
        @Override
        public void onFailure(int reason) {
            Log.d(TAG, "clearLocalServices fail: " + reason);
        }
    });
    
  2. 每隔 10 秒发现主机设备所需的 peed。

    manager.removeServiceRequest(channel, serviceRequest, new WifiP2pManager.ActionListener() {
            @Override
            public void onSuccess() {
                Log.d(TAG, "discovering, removeServiceRequest success");
    
                manager.stopPeerDiscovery(channel, new WifiP2pManager.ActionListener() {
                    @Override
                    public void onSuccess() {
                        Log.d(TAG, "discovering, stopPeerDiscovery success");
    
                        manager.discoverPeers(channel, new WifiP2pManager.ActionListener() {
                            @Override
                            public void onSuccess() {
                                Log.d(TAG, "discovering, discoverPeers success");
    
                                manager.addServiceRequest(channel, serviceRequest, new WifiP2pManager.ActionListener() {
                                    @Override
                                    public void onSuccess() {
                                        Log.d(TAG, "discovering, addServiceRequest success");
    
                                        manager.discoverServices(channel, new WifiP2pManager.ActionListener() {
                                            @Override
                                            public void onSuccess() {
                                                //Log.d(TAG, "discoverServices success");
                                            }
    
                                            @Override
                                            public void onFailure(int reason) {
                                                Log.d(TAG, "discoverServices fail: " + reason);
                                            }
                                        });
                                    }
    
                                    @Override
                                    public void onFailure(int reason) {
                                        Log.d(TAG, "addServiceRequest fail: " + reason);
                                    }
                                });
                            }
    
                            @Override
                            public void onFailure(int reason) {
                                Log.d(TAG, "discoverPeers fail: " + reason);
                            }
                        });
                    }
    
                    @Override
                    public void onFailure(int reason) {
                        Log.d(TAG, "stopPeerDiscovery fail: " + reason);
                    }
                });
            }
    
            @Override
            public void onFailure(int reason) {
                Log.d(TAG, "clearServiceRequests fail: " + reason);
            }
        });
    
  3. 发送连接邀请(通过调用WiFiP2pManager#connect()

    WifiP2pConfig config = new WifiP2pConfig();
    config.deviceAddress = device.deviceAddress;
    config.wps.setup = WpsInfo.PBC;
    
    manager.connect(channel, config, new WifiP2pManager.ActionListener() {
        @Override
        public void onSuccess() {
            Log.d(TAG, "manger.onSuccess with " + device.deviceName);
        }
    
        @Override
        public void onFailure(int errorCode) {
            Log.d(TAG, "Failed connecting to service " + errorCode);
        }
    });
    

  4. 连接提示对话框出现在对等体上。接受连接。
  5. 连接提示对话框从不出现在主机设备上。
第二个问题是,当我调用WiFiP2pManager#connect() 时,它在ActionListenter 的onFailure 方法中返回,错误代码为2。然后,我在5-10 秒后再次调用connect,它在onSuccess 方法中返回。尽管如此,在连接的设备上没有出现连接提示对话框,这意味着我想没有收到连接邀请。

这两个问题是导致应用程序完全无法使用的主要问题。 谁能向我解释我做错了什么或如何处理这些问题?

UPD

为小型发现会话附加日志。
主机日志(nexus 7):http://pastebin.com/ycfqRE4m
对等日志(nexus 10):http://pastebin.com/5kbp6e7A

【问题讨论】:

  • 如果您能提供您正在使用的设备的详细信息,将会很有帮助。一些 Wi-Fi Direct 问题的根源在于制造商驱动程序。
  • public static final int BUSY = 2; - 所以 onFailure(int errorCode) 方法的这个错误值是基板忙,你应该重新发出调用,这就是方法调用在 5-10 秒后成功的原因。
  • @StephenNaicken 我正在使用nexus 7。nexus 10,lenovo vibe s1,三星galaxy a5,htc one。我知道错误代码 BUSY 意味着框架正在做一些不允许执行连接的事情。但它究竟是什么?延迟一段时间后重新调用 WiFiP2pManager.connect() 来处理这个问题是否正确?
  • 文档中没有指导,所以我认为重新调用 connect() 就可以了。您可以使用指数退避重复调用直到它工作,或者每 10 秒重试一次,直到您的应用程序决定放弃。
  • 调用a方法时返回BUSY,但系统由于某种原因无法处理。例如,如果设备正在创建组,然后应用程序调用 discoverPeers(),或者如果应用程序调用 stopDiscovery 却从未启动它。

标签: android wifi-direct


【解决方案1】:

这是我解决第二个问题的方法 我使用线程进行发现并且不使用 Intent 接收器 第三个问题,在连接完成之前不要使用 stopDiscovery

ConnectHelper.manager.discoverPeers(ConnectHelper.channel, null);
    new WiFiDirectScanner().start();

private class WiFiDirectScanner extends Thread {
    @Override
    public void run() {
        while (context != null) {
            try {
                ConnectHelper.manager.requestPeers(ConnectHelper.channel, peerList -> {
                    Collection<WifiP2pDevice> refreshedPeers = peerList.getDeviceList();
                    if (!refreshedPeers.equals(peers)) {
                        peers.clear();
                        peers.addAll(refreshedPeers);

                        scanSuccessWD();
                    }
                });
            } catch (Exception e) {
                e.printStackTrace();
            }

            try {
                Thread.sleep(3000);
            } catch (InterruptedException ignored) {
            }
        }
    }
}

【讨论】:

    猜你喜欢
    • 2012-11-03
    • 1970-01-01
    • 2013-02-23
    • 2012-03-07
    • 1970-01-01
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多