Wifidirect Discovery 找不到对等点

Posted

技术标签:

【中文标题】Wifidirect Discovery 找不到对等点【英文标题】:Wifidirect Discovery not finding peers 【发布时间】:2017-03-13 18:08:49 【问题描述】:

我有一个 wifidirect 应用程序成功发现并连接到对等点,我将该应用程序“附加”到我正在开发的另一个应用程序。该应用程序应该通过蓝牙控制机器人并同时通过Wifidirect进行通信,它有一个“播放按钮”,当它被点击时,它会转到另一个活动,该活动有两个片段,一个是第一个出现的单击“播放”按钮并要求用户连接到对等点(那是我附加了 wifidirect 应用程序)后,连接到第二个片段后,这个片段有游戏界面,它有所有蓝牙部分(连接和控制机器人)。

总而言之:第一个活动有一个播放按钮,单击按钮后,它会转到带有两个片段的第二个活动。第二个活动,必须通过 Wifidirect 连接到对等点,然后必须通过蓝牙连接和控制机器人。

在第二个活动中同时发生 WifiDirect 和蓝牙通信(令人困惑......我知道)

我的问题:如果我只使用 Wifidirect 应用程序,它会成功搜索和连接,但是通过两个应用程序的“融合”,它只会永远搜索而一无所获。知道发生了什么吗?可能是为了更多的交流或在同一活动中发生的许多事情?如果我感到困惑,请告诉我。

我的 Wifidiscovery 活动:

public class WiFiServiceDiscoveryActivity extends Activity implements
    DeviceClickListener, Handler.Callback, MessageTarget,
    ConnectionInfoListener 

public static final String TAG = "wifidirectdemo";

// TXT RECORD properties
public static final String TXTRECORD_PROP_AVAILABLE = "available";
public static final String SERVICE_INSTANCE = "_wifidemotest";
public static final String SERVICE_REG_TYPE = "_presence._tcp";

public static final int MESSAGE_READ = 0x400 + 1;
public static final int MY_HANDLE = 0x400 + 2;
private WifiP2pManager manager;

static final int SERVER_PORT = 4545;

private final IntentFilter intentFilter = new IntentFilter();
private Channel channel;
private BroadcastReceiver receiver = null;
private WifiP2pDnsSdServiceRequest serviceRequest;

private Handler handler = new Handler(this);
private jogar chatFragment;
private WiFiDirectServicesList servicesList;

private TextView statusTxtView;
Button botaorecomecar;

public Handler getHandler() 
    return handler;


public void setHandler(Handler handler) 
    this.handler = handler;


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    statusTxtView = (TextView) findViewById(R.id.status_text);
    botaorecomecar = (Button) findViewById(R.id.botaorecomecar);

    intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
    intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
    intentFilter
            .addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
    intentFilter
            .addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);

    manager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
    channel = manager.initialize(this, getMainLooper(), null);
    startRegistrationAndDiscovery();

    servicesList = new WiFiDirectServicesList();
    getFragmentManager().beginTransaction()
            .add(R.id.container_root, servicesList, "services").commit();

    botaorecomecar.setOnClickListener(new View.OnClickListener() 
        @Override
        public void onClick(View v) 
            Intent intent = getIntent();
            finish();
            startActivity(intent);
        


    );





@Override
protected void onRestart() 
    Fragment frag = getFragmentManager().findFragmentByTag("services");
    if (frag != null) 
        getFragmentManager().beginTransaction().remove(frag).commit();
    
    super.onRestart();


@Override
protected void onStop() 
    if (manager != null && channel != null) 
        manager.removeGroup(channel, new ActionListener() 

            @Override
            public void onFailure(int reasonCode) 
                Log.d(TAG, "Disconecção falhada. Razão: :" + reasonCode);
            

            @Override
            public void onSuccess() 
            

        );
    
    super.onStop();


/**
 * Registers a local service and then initiates a service discovery
 */
private void startRegistrationAndDiscovery() 
    Map<String, String> record = new HashMap<String, String>();
    record.put(TXTRECORD_PROP_AVAILABLE, "visivel");

    WifiP2pDnsSdServiceInfo service = WifiP2pDnsSdServiceInfo.newInstance(
            SERVICE_INSTANCE, SERVICE_REG_TYPE, record);
    manager.addLocalService(channel, service, new ActionListener() 

        @Override
        public void onSuccess() 
            appendStatus("Serviço local adicionado");
        

        @Override
        public void onFailure(int error) 
            appendStatus("Falha ao adicionar serviço");
        
    );

    discoverService();



private void discoverService() 

    /*
     * Register listeners for DNS-SD services. These are callbacks invoked
     * by the system when a service is actually discovered.
     */

    manager.setDnsSdResponseListeners(channel,
            new DnsSdServiceResponseListener() 

                @Override
                public void onDnsSdServiceAvailable(String instanceName,
                                                    String registrationType, WifiP2pDevice srcDevice) 

                    // A service has been discovered. Is this our app?

                    if (instanceName.equalsIgnoreCase(SERVICE_INSTANCE)) 

                        // update the UI and add the item the discovered
                        // device.
                        WiFiDirectServicesList fragment = (WiFiDirectServicesList) getFragmentManager()
                                .findFragmentByTag("serviços");
                        if (fragment != null) 
                            WiFiDevicesAdapter adapter = ((WiFiDevicesAdapter) fragment
                                    .getListAdapter());
                            WiFiP2pService service = new WiFiP2pService();
                            service.device = srcDevice;
                            service.instanceName = instanceName;
                            service.serviceRegistrationType = registrationType;
                            adapter.add(service);
                            adapter.notifyDataSetChanged();
                            Log.d(TAG, "onBonjourServiceAvailable "
                                    + instanceName);
                        
                    

                
            , new DnsSdTxtRecordListener() 

                /**
                 * A new TXT record is available. Pick up the advertised
                 * buddy name.
                 */
                @Override
                public void onDnsSdTxtRecordAvailable(
                        String fullDomainName, Map<String, String> record,
                        WifiP2pDevice device) 
                    Log.d(TAG,
                            device.deviceName + " é "
                                    + record.get(TXTRECORD_PROP_AVAILABLE));
                
            );

    // After attaching listeners, create a service request and initiate
    // discovery.
    serviceRequest = WifiP2pDnsSdServiceRequest.newInstance();
    manager.addServiceRequest(channel, serviceRequest,
            new ActionListener() 

                @Override
                public void onSuccess() 
                    appendStatus("Adicionado pedido de descoberta de serviços");
                

                @Override
                public void onFailure(int arg0) 
                    appendStatus("Falha ao adicionar pedido de descoberta de serviços");
                
            );
    manager.discoverServices(channel, new ActionListener() 

        @Override
        public void onSuccess() 
            appendStatus("Descoberta de serviços iniciada");
        

        @Override
        public void onFailure(int arg0) 
            appendStatus("Descoberta de serviços falhada");

        
    );


@Override
public void connectP2p(WiFiP2pService service) 
    WifiP2pConfig config = new WifiP2pConfig();
    config.deviceAddress = service.device.deviceAddress;
    config.wps.setup = WpsInfo.PBC;
    if (serviceRequest != null)
        manager.removeServiceRequest(channel, serviceRequest,
                new ActionListener() 

                    @Override
                    public void onSuccess() 
                    

                    @Override
                    public void onFailure(int arg0) 
                    
                );

    manager.connect(channel, config, new ActionListener() 

        @Override
        public void onSuccess() 
            appendStatus("A conectar a um serviço");
        

        @Override
        public void onFailure(int errorCode) 
            appendStatus("Falha ao conectar a serviço");
        
    );


@Override
public boolean handleMessage(Message msg) 
    switch (msg.what) 
        case MESSAGE_READ:
            byte[] readBuf = (byte[]) msg.obj;
            // construct a string from the valid bytes in the buffer
            String readMessage = new String(readBuf, 0, msg.arg1);
            Log.d(TAG, readMessage);
            (chatFragment).pushMessage(readMessage);
            break;

        case MY_HANDLE:
            Object obj = msg.obj;
            (chatFragment).setChatManager((ChatManager) obj);

    
    return true;


@Override
public void onResume() 
    super.onResume();
    receiver = new WiFiDirectBroadcastReceiver(manager, channel, this);
    registerReceiver(receiver, intentFilter);


@Override
public void onPause() 
    super.onPause();
    unregisterReceiver(receiver);


@Override
public void onConnectionInfoAvailable(WifiP2pInfo p2pInfo) 
    Thread handler = null;
    /*
     * The group owner accepts connections using a server socket and then spawns a
     * client socket for every client. This is handled by @code
     * GroupOwnerSocketHandler
     */

    if (p2pInfo.isGroupOwner) 
        Log.d(TAG, "Conectado como GroupOwner");
        try 
            handler = new GroupOwnerSocketHandler(
                    ((MessageTarget) this).getHandler());
            handler.start();
         catch (IOException e) 
            Log.d(TAG,
                    "Falha ao criar uma thread de servidor - " + e.getMessage());
            return;
        
     else 
        Log.d(TAG, "Conectado como peer");
        handler = new ClientSocketHandler(
                ((MessageTarget) this).getHandler(),
                p2pInfo.groupOwnerAddress);
        handler.start();
    
    chatFragment = new jogar();
    getFragmentManager().beginTransaction()
            .replace(R.id.container_root, chatFragment).commit();
    statusTxtView.setVisibility(View.GONE);


public void appendStatus(String status) 
    String current = statusTxtView.getText().toString();
    statusTxtView.setText(current + "\n" + status);

【问题讨论】:

【参考方案1】:

您的代码看起来正确,应该可以按预期工作。但是,我看到一种情况可能导致服务被忽略(来自您上面的代码):

 // A service has been discovered. Is this our app?

 if (instanceName.equalsIgnoreCase(SERVICE_INSTANCE)) 

当发现一个服务时,您的应用程序正在按服务名称过滤它们,我认为这两个应用程序之间的混淆在于它们使用不同的服务名称。 您可以尝试删除此“if”语句并再次测试应用程序吗?

希望这会有所帮助,

祝你好运。

【讨论】:

以上是关于Wifidirect Discovery 找不到对等点的主要内容,如果未能解决你的问题,请参考以下文章

CMakeLists - 使链接器找不到文件

Android 同时运行 Wifi Lan 和 Wifi Direct

stm32f769ni-discovery编译例程需要修改

数据包路由如何在 Wifi-Direct 组中进行?

Android WiFiDirect 服务发现混乱

对 BigQuery 查询的错误响应:kind:discovery#restDescription 而不是 bigquery#queryResults