I'm trying to implement JmDNS discovery for communication between an Android app and a desktop application. I have followed the following tutorial: http://home.heeere.com/tech-androidjmdns.html
The Android app registers a service and the desktop application adds a listener for the service. I've got it working perfectly fine with three out of four of my devices, but with the fourth one (a Samsung Galaxy Tab 10.1 PT7500 running Android 3.2) I can't resolve the service.
My handler receives the serviceAdded
event, but no serviceResolved
event.
I have also tried calling jmdns.requestServiceInfo
and jmdns.getServiceInfo
, but the former does nothing and the latter times out and returns null.
The jmdns-browser, however, is able to resolve the service just fine, so it's not the device. There is no firewall on either of the devices. The service always uses an IPv4 address.
Does anybody have an idea what could cause this problem?
Code for starting the service:
jmdns = JmDNS.create(wifiAddress);
ServiceInfo serviceInfo = ServiceInfo.create(Constants.SERVICE_TYPE,
Constants.SERVICE_NAME, Constants.ZEROCONF_PORT, "my service");
HashMap<String, String> deviceInfoMap = new HashMap<String, String>();
deviceInfoMap.put(Constants.KEY_DEVICE_NAME, getDeviceName());
deviceInfoMap.put(Constants.KEY_DEVICE_ID, getDeviceId());
// ...
serviceInfo.setText(deviceInfoMap);
jmdns.registerService(serviceInfo);
Code for the client / listener:
jmdns = JmDNS.create();
jmdns.addServiceListener(Constants.SERVICE_TYPE, serviceListener = new ServiceListener() {
@Override
public void serviceResolved(ServiceEvent event) {
System.out.println("Service resolved: " + event.getName() +
" of type " + event.getType());
}
@Override
public void serviceRemoved(ServiceEvent event) {
System.out.println("Service removed: " + event.getName() +
" of type " + event.getType());
}
@Override
public void serviceAdded(ServiceEvent event) {
System.out.println("Service added: " + event.getName() +
" of type " + event.getType());
ServiceInfo info = jmdns.getServiceInfo(event.getType(), event.getName());
System.out.println("Service info: " + info); // --> null
}
});
Output:
Service added: my service @ GT-P7500 of type _mytype._tcp.local.
Service info: null
Service added: my service @ Galaxy Nexus of type _mytype._tcp.local.
Service info: [ServiceInfoImpl@183779345
name: 'my service @ Galaxy Nexus ._mytype._tcp.local.'
address: '/192.168.1.154:4242 ' status: 'DNS: myhost.local.
state: probing 1 task: null', has data
deviceName: Galaxy Nexus
deviceId: <id>
displayDensity: XHDPI
]
Checking out the latest source code version from the github repository did the trick. Discovering the service now works just fine on all devices. (Note: I was using JmDNS version 3.4.1 which I had downloaded from sourceforge before)
Having skimmed through the SVN history, there seem to be a couple of commits related to problems with resolving services since the 3.4.1 release.
Edit: Replaced svn with github repository since jmdns has moved there.
Use JmDNS.create(InetAddress addr, String name)
instead of JmDNS.create()
. In more recent versions of Android, JmDNS needs to know more about the local device and the network interface it is listening on.
JmDNS jmdns; // somewhere global
// In a background thread
public void buildJmDNS() {
InetAddress addr = InetAddress.getLocalHost();
String hostname = InetAddress.getByName(addr.getHostName()).toString();
try {
jmdns = JmDNS.create(addr, hostname); // throws IOException
} catch (IOException e) {
e.printStackTrace(); // handle this if you want
}
}
I had the same issue you are experiencing and this solved it for me. I have tried to find the example I had found that shows why this is necessary, but I cannot.
来源:https://stackoverflow.com/questions/14340458/jmdns-cant-resolve-service