2013-08-07 14 views
6

Sto cercando di ottenere il mHost di NsdServiceInfo passato come parametro a NsdManager.DiscoveryListener.onServiceFound() ma è nullo. Ho due dispositivi Android in cui il dispositivo 1 è il server e il dispositivo 2 è il client.L'host è nullo in NsdServiceInfo di NsdManager.DiscoveryListener.onServiceFound

Questo è come mi registrare il server nel dispositivo 1

public void registerService(int port, InetAddress myIp) { 
    NsdServiceInfo serviceInfo = new NsdServiceInfo(); 
    serviceInfo.setPort(port); 
    serviceInfo.setServiceName(this.serviceName); 
    serviceInfo.setServiceType(SERVICE_TYPE); 
    serviceInfo.setHost(myIp); 

    this.nsdManager.registerService(
      serviceInfo, NsdManager.PROTOCOL_DNS_SD, registrationListener); 
} 

e questo è come mi inizializzare la DiscoveryListener

public void initializeDiscoveryListener() { 
    discoveryListener = new NsdManager.DiscoveryListener() { 

     @Override 
     public void onServiceFound(NsdServiceInfo service) { 
      Log.d(TAG, "Service discovery success" + service); 
      if (!service.getServiceType().equals(SERVICE_TYPE)) { 
       Log.d(TAG, "Unknown Service Type: " + service.getServiceType()); 
      } else if (service.getHost() == myIp) { 
       Log.d(TAG, "Same machine: " + service.getHost()); 
      } else if (service.getServiceName().contains(serviceName)){ 
       nsdManager.resolveService(service, resolveListener); 
      } 
     } 
    ... 
    } 
} 

Ma service.getHost() restituisce null.
Qualche suggerimento?

risposta

13

Ho appena incontrato lo stesso problema e sono riuscito a risolverlo con un piccolo aiuto dalla pagina di Google sulla scoperta della rete.

http://developer.android.com/training/connect-devices-wirelessly/nsd.html

Il problema è che le informazioni di connessione non è noto quando il servizio è scoperto. Devi risolverlo prima che getHost() funzioni.

hai già la linea:

nsdManager.resolveService(service, resolveListener); 

La variabile resolveListener contiene callback per il successo e il fallimento. Si desidera utilizzare getHost() quando le informazioni sulla connessione sono state determinate correttamente. Ecco il listener di risoluzione di Google:

public void initializeResolveListener() { 
     resolveListener = new NsdManager.ResolveListener() { 

     @Override 
     public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) { 
      // Called when the resolve fails. Use the error code to debug. 
      Log.e(TAG, "Resolve failed" + errorCode); 
     } 

     @Override 
     public void onServiceResolved(NsdServiceInfo serviceInfo) { 
      Log.e(TAG, "Resolve Succeeded. " + serviceInfo); 

      if (serviceInfo.getServiceName().equals(mServiceName)) { 
       Log.d(TAG, "Same IP."); 
       return; 
      } 
      service = serviceInfo; 
      int port = service.getPort(); 
      InetAddress host = service.getHost(); // getHost() will work now 
     } 
    }; 
} 
+0

Il codice di esempio in Android non è aggiornato, è necessario aggiornare il codice dopo la modifica del codice. : D – mxi1

+0

Sfortunatamente, resolveService (...) non funziona affatto. Quando si riceve .onServiceDiscovered(), un ".local" sarà sempre aggiunto (da NsdManager!) Al tipo di protocollo, tuttavia questo ".local" confonde il resolveService(). ERRORE SCONOSCIUTO è il risultato. Se viene rimosso il .local, non viene ricevuta alcuna richiamata dal (sempre nuovo Resolvelistener) nella prima chiamata, mentre la seconda chiamata restituisce l'errore NsdManager.FAILURE_ALREADY_ACTIVE: // = 3. Ma dal momento che è una nuova istanza creata su ogni chiamata, questo non ha senso, a meno che non ci sia un meccanismo Singleton in agguato qui. Immaturità profondamente fastidiosa. – carl

+0

Posso aggiungere che il motivo per cui si eseguono più chiamate di risoluzione è semplicemente il rilevamento di più di un servizio sulla rete locale. – carl