Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 942
Eldoth Avatar asked Aug 07 '13 04:08

Eldoth


1 Answers

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
        }
    };
}
like image 146
Eli Connelly Avatar answered Oct 23 '22 05:10

Eli Connelly