I\'m trying to implement a class to discover services on the network. I\'ve tried working with Android\'s NSD and it does discover the services fine, but it supports only AP
I am the author of ZeroConf Browser for Android and I use the open source Library JmDNS for all my resolving. It works great but there are a few tricks to getting it to work properly.
In your Android manifest.xml make sure you have these permissions at least.
Before starting the activity you must allow multi-cast packets by acquiring a multicast lock.
@Override
protected void onStart() {
Log.i(TAG, "Starting ServiceActivity...");
super.onStart();
try {
Log.i(TAG, "Starting Mutlicast Lock...");
WifiManager wifi = (WifiManager) this.getSystemService(Context.WIFI_SERVICE);
// get the device ip address
final InetAddress deviceIpAddress = getDeviceIpAddress(wifi);
multicastLock = wifi.createMulticastLock(getClass().getName());
multicastLock.setReferenceCounted(true);
multicastLock.acquire();
Log.i(TAG, "Starting ZeroConf probe....");
jmdns = JmDNS.create(deviceIpAddress, HOSTNAME);
jmdns.addServiceTypeListener(this);
} catch (IOException ex) {
Log.e(TAG, ex.getMessage(), ex);
}
Log.i(TAG, "Started ZeroConf probe....");
}
private InetAddress getDeviceIpAddress(WifiManager wifi) {
InetAddress result = null;
try {
// default to Android localhost
result = InetAddress.getByName("10.0.0.2");
// figure out our wifi address, otherwise bail
WifiInfo wifiinfo = wifi.getConnectionInfo();
int intaddr = wifiinfo.getIpAddress();
byte[] byteaddr = new byte[] { (byte) (intaddr & 0xff), (byte) (intaddr >> 8 & 0xff),
(byte) (intaddr >> 16 & 0xff), (byte) (intaddr >> 24 & 0xff) };
result = InetAddress.getByAddress(byteaddr);
} catch (UnknownHostException ex) {
Log.w(TAG, String.format("getDeviceIpAddress Error: %s", ex.getMessage()));
}
return result;
}
And don't forget on stopping the scan to unlock the multicast lock and shut down JmDNS.
@Override
protected void onStop() {
Log.i(TAG, "Stopping ServiceActivity...");
super.onStop();
stopScan();
}
private static void stopScan() {
try {
if (jmdns != null) {
Log.i(TAG, "Stopping ZeroConf probe....");
jmdns.unregisterAllServices();
jmdns.close();
jmdns = null;
}
if (multicastLock != null) {
Log.i(TAG, "Releasing Mutlicast Lock...");
multicastLock.release();
multicastLock = null;
}
} catch (Exception ex) {
Log.e(TAG, ex.getMessage(), ex);
}
}
Most importanty don't use the default constructor. You must use the IP Address Constructor. I noticed in your code you are just doing JmDNS.create(). I think for some reason the only way it works on Android is to use the contructor below.
jmdns = JmDNS.create(deviceIpAddress, HOSTNAME);