Android NSD onServiceFound() not getting called
Asked Answered
A

4

7

First time trying to do IP Discovery in Android. I used the http://developer.android.com/training/connect-devices-wirelessly/nsd.html#discover and wrote the code. I am not registering the device, just Discovering Services in the network. When I run the project in emulator or device the onDiscoveryStarted() gets called, but the onServiceFound() is never called. Please find my Code below. Any input is much appreciated. Thanks!

public class MainActivity extends AppCompatActivity {

    private Button discoverButton;

    Context mContext;

    NsdManager mNsdManager;
    NsdManager.ResolveListener mResolveListener;
    NsdManager.DiscoveryListener mDiscoveryListener;
    NsdManager.RegistrationListener mRegistrationListener;

    public static final String SERVICE_TYPE = "_http._tcp.";
    public static final String TAG = "MyApp_MAIN_CLIENT";
    public String mServiceName = "MyApp";

    /*
    * public static final String SERVICE_TYPE = "_http._tcp.";
    public static final String TAG = "NsdHelper";
    public String mServiceName = "NsdChat";
    * */

    NsdServiceInfo mService;
    private Handler mUpdateHandler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mNsdManager = (NsdManager) this.getSystemService(Context.NSD_SERVICE);
        discoverButton = (Button) findViewById(R.id.netButton);
        discoverButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(android.view.View v) {
                initializeDiscoveryListener();
                initializeResolveListener();
                discoverServices();

            }
        });

    }

    public void discoverServices() {
        mNsdManager.discoverServices(
                SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener);
    }


    public void initializeDiscoveryListener() {

        // Instantiate a new DiscoveryListener
        mDiscoveryListener = new NsdManager.DiscoveryListener() {

            //  Called as soon as service discovery begins.
            @Override
            public void onDiscoveryStarted(String regType) {
                Log.d(TAG, "Service discovery started");
            }

            @Override
            public void onServiceFound(NsdServiceInfo service) {
                // A service was found!  Do something with it.
                Log.d(TAG, "Service discovery success" + service);
                if (!service.getServiceType().equals(SERVICE_TYPE)) {
                    // Service type is the string containing the protocol and
                    // transport layer for this service.
                    Log.d(TAG, "Unknown Service Type: " + service.getServiceType());
                } /*else if (service.getServiceName().equals(mServiceName)) {
                    // The name of the service tells the user what they'd be
                    // connecting to. It could be "Bob's Chat App".
                    Log.d(TAG, "Same machine: " + mServiceName);
                }
                //else if (service.getServiceName().contains("NsdChat")){*/
                else{
                    mNsdManager.resolveService(service, mResolveListener);
                }
            }

            @Override
            public void onServiceLost(NsdServiceInfo service) {
                // When the network service is no longer available.
                // Internal bookkeeping code goes here.
                Log.e(TAG, "service lost" + service);
            }

            @Override
            public void onDiscoveryStopped(String serviceType) {
                Log.i(TAG, "Discovery stopped: " + serviceType);
            }

            @Override
            public void onStartDiscoveryFailed(String serviceType, int errorCode) {
                Log.e(TAG, "Discovery failed: Error code:" + errorCode);
                mNsdManager.stopServiceDiscovery(this);
            }

            @Override
            public void onStopDiscoveryFailed(String serviceType, int errorCode) {
                Log.e(TAG, "Discovery failed: Error code:" + errorCode);
                mNsdManager.stopServiceDiscovery(this);
            }
        };
    }// end of initializeListener()


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

            @Override
            public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {
                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;
                }
                mService = serviceInfo;
                int port = mService.getPort();
                InetAddress host = mService.getHost();
                Log.d(TAG,host.toString());
            }
        };
    }//end of initializeResolveListener


    @Override
    protected void onPause() {
        super.onPause();
        stopDiscovery();
        tearDown();

    }

    @Override
    protected void onResume() {
        super.onResume();
        discoverServices();
    }

    @Override
    protected void onDestroy() {
        tearDown();
        super.onDestroy();
    }

    public void stopDiscovery() {
        mNsdManager.stopServiceDiscovery(mDiscoveryListener);
    }


    public void tearDown() {
        mNsdManager.unregisterService(mRegistrationListener);
    }
}
Airfield answered 22/4, 2016 at 14:51 Comment(3)
"I am not registering the device, just Discovering Services in the network". That's the reason. You can't discover a service that hasn't been registered. One device should register the service which other devices will discover... (An advice regarding the NSD sample: don't register and discover the service on the same device)Characteristic
Android NSD documentation specifically says that 'Registering' step is optional. If you don't want to register your device, go to step 2: Discovering other servicesAirfield
Try to remove last dot from "_http._tcp." -> "_http._tcp";Ti
A
7

From NdsManager documentation page:

The API currently supports DNS based service discovery and discovery is currently limited to a local network over Multicast DNS.

From this Local networking limitations emulator docs page:

Currently, the emulator does not support IGMP or multicast.

Hope this will help you

Ange answered 25/10, 2017 at 7:21 Comment(0)
O
5

Probably due to the age of this post, I hope you already found a solution.

If not, my experience is that the Android Emulator (API level 25) does not provide a full network stack and the service discovery through NSD isn't working.

I switched to debugging on a real device (like an Android TV or tablet) and then my whole NSD/Bonjour-like setup was working. The methods of the DiscoveryListener and the ResolveListener were called and an IP and port (in my case) were retrieved.

Oblige answered 16/3, 2017 at 21:2 Comment(0)
I
1

After some hours working with Android NSD, I discovered that this library does not work with routers that don't support Multicast. While the other answers may are correct, this could also be the cause of your problem. Possible solutions: enable Multicast on your router if possible, or use another network library.

Inunction answered 6/8, 2019 at 14:37 Comment(0)
M
-1

The Network Service Discovery Manager class provides the API to discover services on a network. This will work when your device is connected to the same WIFI network as that of the device providing the service. Hope this helps!! Happy Coding!!

Motorboating answered 23/5, 2019 at 8:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.