You need to ensure that you are not passing in a listener object that has already been registered. You can see the commit that resulted in this behavior change here.
Here is the commit message text:
Document and enforce "one request per Listener" rule
The API and implementation of NsdManager imply that a separate
Listener is to be used for each active registration or discovery
request. This isn't formally documented or properly enforced, and
weird and unpredictable things happen if an application uses a
Listener for more than one request at a time.
Update documentation to make this an explicit requirement.
Enforce the restriction when a new request is submitted for
processing; if the Listener is already being used to track an active
request, throw an exception.
Document the fact that apps should unregister services and cancel
service discoveries when the app is stopped (in KitKat and prior
releases, they'll leak if this isn't done.)
Re-order "release the Listener" operation to occur before the Listener
callback, so that the Listener can be reused by the application once
the callback has been entered - this eliminates a race condition.
Document this.
Pass 2: typos, added documentation about API level, changed to using
an explicitly defined return value for "busy listener".
Also, just a warning that if you downloaded the NsdChat sample project from the Android Developers site (i.e. NsdChat.zip
or something along those lines), that project code is likely out of date.
Try using the latest code on the master branch instead... you can copy and paste it into your sample project from here.