androidnetwork-programminglistenerdiscovery

Host is null in NsdServiceInfo of NsdManager.DiscoveryListener.onServiceFound


I'm trying to get the mHost of the NsdServiceInfo passed as parameter to NsdManager.DiscoveryListener.onServiceFound() but it's null. I have two android devices where device 1 is the server and device 2 is the client.

This is how I register the server in the device 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);
}

And this is how I initialize the 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);
            }
        }
   ...
   }
}

But service.getHost() returns null.
Any suggestion?


Solution

  • I just ran across this same issue and managed to solve it with a little help from Google's page on network discovery.

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

    The problem is that the connection information isn't known when the service is discovered. You have to resolve it first before getHost() will work.

    You already have the line:

        nsdManager.resolveService(service, resolveListener);
    

    The resolveListener variable contains callbacks for success and failure. You want to use getHost() when the connection information has been successfully determined. Here's the resolve listener from 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
            }
        };
    }