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);
}
}
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
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With