I'm trying to run an application using Android Native Service Discovery but sometimes when I run the application, it doesn't discover all services from my network. I'm running the code from https://github.com/joeluchoa/nsd using four galaxy nexus and most of the times each of them discoveries different number of services at the same time.
Basically I run a service with a ServerSocket:
ServerSocket server = new ServerSocket(0);
Log.i(TAG, "IP " + server.getInetAddress()
+ ", running on port " + server.getLocalPort());
Intent intent = new Intent(MySocket.this,
MyPresence.class);
intent.putExtra("PORT", server.getLocalPort());
startService(intent);
Then I publish it using the method registerService from NsdManager:
NsdServiceInfo serviceInfo = new NsdServiceInfo();
serviceInfo.setServiceName(Build.SERIAL + "-" + new Date().getTime());
serviceInfo.setServiceType(SERVICE_TYPE);
serviceInfo.setPort(port);
mNsdManager.registerService(serviceInfo, NsdManager.PROTOCOL_DNS_SD,
mRegistrationListener);
To discover the services I use the method discoverServices from NsdManager:
mNsdManager.discoverServices(SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD,
mDiscoveryListener);
With mDiscoveryListener as follows:
mDiscoveryListener = new NsdManager.DiscoveryListener() {
@Override
public void onDiscoveryStarted(String regType) {
Log.d(TAG, "Service discovery started");
}
@Override
public void onServiceFound(NsdServiceInfo service) {
Log.d(TAG, "Service discovery success");
Log.d(TAG, String.format("%s %s %s %d",
service.getServiceName(), service.getServiceType(),
service.getHost(), service.getPort()));
if (!service.getServiceType().contains(SERVICE_TYPE)) {
Log.d(TAG,
"Unknown Service Type: " + service.getServiceType());
} else if (service.getServiceName().equals(mServiceName)) {
Log.d(TAG, "Same machine: " + mServiceName);
} else {
mNsdManager.resolveService(service, mResolveListener);
}
}
@Override
public void onServiceLost(NsdServiceInfo service) {
Log.e(TAG, "service lost" + service);
}
@Override
public void onDiscoveryStopped(String serviceType) {
Log.i(TAG, serviceType + " Discovery stopped: " + serviceType);
}
@Override
public void onStartDiscoveryFailed(String serviceType, int errorCode) {
Log.e(TAG, serviceType + " Discovery failed: Error code:"
+ errorCode);
mNsdManager.stopServiceDiscovery(this);
}
@Override
public void onStopDiscoveryFailed(String serviceType, int errorCode) {
Log.e(TAG, serviceType + " Discovery failed: Error code:"
+ errorCode);
mNsdManager.stopServiceDiscovery(this);
}
};
Am i doing something wrong? Does anybody know a solution or a workaround for this?
To discover all services of the connected network just change the service type you are discovering,
public static final String SERVICE_TYPE = "_services._dns-sd._udp";
I'm afraid that there are still bugs in the implementation that cause it to miss services. I've done a couple days of testing with multiple Android devices and a MacBook, and it just doesn't work all the time. I documented my findings on a bug report over in the Android bug tracker: https://code.google.com/p/android/issues/detail?id=178080
I tend to think the whole NSD implementation in Android must be a bit flaky. I also have a simple Activity just to demonstrate the lifecycle (no Sockets are opened), and sometimes it works, and sometimes it does not work. I simply don't get it. Here is the Activity if anybody has some insight:
https://github.com/mholzel/Dump/blob/master/NetworkServiceDiscoveryViaWifi.java
On the other hand, Wifi Direct based NSD seems to be very reliable for me:
https://github.com/mholzel/Dump/blob/master/NetworkServiceDiscoveryViaWifiDirect.java
Note that neither of these Activities have any resources, so just add the Activities to your Manifest with the proper permissions.
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