Host is null in NsdServiceInfo of NsdManager.DiscoveryListener.onServiceFound
Asked Answered
E

1

9

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?

Elum answered 7/8, 2013 at 4:30 Comment(0)
E
20

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
        }
    };
}
Exaggerative answered 25/8, 2013 at 1:25 Comment(4)
The sample code in Android is out of date, they should update the code following your code change. :DAmalea
Unfortunately, the resolveService(...) does not work at all. When receiving .onServiceDiscovered(), a ".local" will always be added (by NsdManager!) to the protocoltype, however this ".local" confuses the resolveService(). UNKNOWN ERROR is the result. If the .local is removed, no callbacks are received from the (always new Resolvelistener) in the first call, while the second call gives error NsdManager.FAILURE_ALREADY_ACTIVE: //=3. But since it is a new instance created on each call, this is meaningless, unless there is a Singleton mechanism lurking here. Deeply annoying immaturity.Ladybird
I can add that the reason for doing several resolve calls is simply that more than one service is discovered on the local network.Ladybird
@Ladybird ping me if you have the solution! because I m stuck on this issue for two days now! I want a p2p chatBeaune

© 2022 - 2024 — McMap. All rights reserved.