40

I'm working with a Droid / Android 2.0.1 and encountering an issue apparently many people have: I'm unable to discover services using the one pure-Java zeroconf library I know of, jmDNS. (Apple's Bonjour, while it works on Linux and Windows Java, I believe would be harder to port to Android because of reliance on native code.)

I can create services, but not discover them. I'm trying to make sense of what's going on.

There is an ongoing issue report here; related to multicast and IPv6, but seems to be throwing users of jmDNS, too: http://code.google.com/p/android/issues/detail?id=2323

Any idea why this person might be having success? See comment 22 in the bug report. (I'm new to SO, so can't post more than one URL.)

I have tested their code, but without any luck.

Has anyone successfully accomplished zeroconf service discovery on Android, using jmDNS or another library?

Is it possible my discovery issue is related to the IPv6 multicast problem?

Roman Nurik
  • 29,665
  • 7
  • 84
  • 82
Peter Kirn
  • 503
  • 1
  • 5
  • 6
  • There is no comment 22 in that bug report. It only goes to 14. – CommonsWare Mar 19 '10 at 00:19
  • Looks like the Issue Tracker link should be: http://code.google.com/p/android/issues/detail?id=2917 – Roman Nurik Mar 19 '10 at 00:41
  • Sorry, corrected: http://code.google.com/p/android/issues/detail?id=2917#c22 – Peter Kirn Mar 19 '10 at 00:43
  • Apologies I can't ask a more specific question. The problem is, it's difficult to troubleshoot a situation when nothing happens. ;) I'm surprised there aren't more people who have tried this, but maybe that's because of the sorry state of Java zeroconf libraries ... a chicken and egg problem. – Peter Kirn Mar 19 '10 at 00:51
  • The zeroconf protocol is intentionally very, very simple. I'd suggest writing a bare bones client straight off the RFC and see if you're receiving packets correctly. It shouldn't have anything to do with multicast quirkiness but it certainly could be related to issues with sending/receiving broadcast UDP packets. – Rakis Apr 19 '10 at 16:35
  • Very detailed article about Android and Bonjour: http://andriydruk.com/post/mdnsresponder/ – delkant Nov 17 '16 at 18:31

5 Answers5

13

I'm new as well otherwise I would have just left a comment on smountcastle's answer which is mostly correct. I have just been dealing with the exact same issue on a Droid running Android 2.1. I found that I needed to set the MulticastLock to reference-counted otherwise it seemed to be released automatically.

AndroidManifest.xml:
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />

// Networking code:
WifiManager wifi = getSystemService( Context.WIFI_SERVICE );
MulticastLock lock = wifi.createMulticastLock("fliing_lock");
lock.setReferenceCounted(true);
lock.acquire();

Just make sure to call lock.release() when you're done with it. This may only be necessary for Android 2.0+, The Droid is my only test device currently, so I can't say for sure.

Churlbong
  • 148
  • 6
  • So close to being able to make general comments... I am using JmDNS, I have had success with it on a Motorola Droid running 2.1-update1 using the MulticastLock approach. Just recently got an HTC Incredible running the same version of Android, and service discovery doesn't work using the exact same code. I've been pulling my hair out on that one, good luck... – Churlbong May 01 '10 at 16:33
  • Can you add some code how are you calling everything.. I have tried by adding the CHANGE_WIFI_MULTICASR_STATE permission..but i am still not getting any result. – mudit Jan 11 '11 at 07:27
  • Thanks, Churlbong - out of curiosity, are you using jmDNS or just writing the client implementation outright? (or using another library)? I'll give this a try, as my lock code isn't quite the same and I'm not sure I was aware it also had a separate permission independent of the network permission. ;) – Peter Kirn Feb 09 '11 at 17:00
8

I managed to cross-compile Bonjour for Android and get it running much the same way Apple intends it to run on embedded devices like printers. Here is the build script.

Here is a small convenience wrapper to get it working as you'd expect.

We are using the client_shim layer from the Bonjour distribution to wrap all access to the embedded mDNS implementation via the usual dns_sd.h API. You do not use the idiom with the filehandles and the select with the shim layer.

The client_shim layer is not exactly good supported by Apple - in fact I found typos in variable names, but it is working nevertheless. You will need to apply this patch to include the correct header files, fix the typos and get logging via the Android APIs.

One more thing: You need to acquire and hold the MultiCast Lock from within your Java code, otherwise you won't find anybody else. See the example here.

Other than that, I have it working on Android API Level 8 and we are maintaining a prebuilt library of Bonjour for Android, though I am not sure whether this is ok as per license.

Edited:

The version in the prebuilts is 330.10, newer ones with client_shim as static libraries fail to compile with MSVC2010 on windows, so we kept this one.

Good Luck!

sradomski
  • 436
  • 5
  • 8
  • Some of the links are dead, but I managed to find prebuilt examples. Can these Classes(Publisher, Subscriber, Node, Discovery) be used to communicate with an Apple device that uses their implementation of Bonjour or would the Apple device have to be running umundo aswell? – Adrian Jandl Feb 27 '14 at 19:52
  • We still have prebuilts, but they moved into a [tarball](http://umundo.tk.informatik.tu-darmstadt.de/prebuilt/0.4.3/) which is downloaded at configure-time. For every platform but darwin, there is a libmdnsembedded inside. uMundo is ZeroMQ + mDNS for pub/sub - if you just want to find services, use the libmdnsembedded and the dns_sd.h without the select as done in the client_shim implementation. – sradomski Feb 28 '14 at 15:36
  • I would like to just find services through my Android device. Are there any examples to use the `libmDNSEmbedded.a` file on an android device in conjunction with dns_sd.h? Is there a java wrapper for simple service discovery? – Adrian Jandl Feb 28 '14 at 23:40
  • You can use umundo and ignore everything but the discovery subsystem. Here is [an example project](https://github.com/tklab-tud/umundo/tree/master/examples/android/umundo-pingpong) for umundo on android. The Discovery object can be used to browse / advertise services per service type / domain. Don't forget to unbrowse / unadvertise when you are done. Continue on umundo issue tracker if you choose to do so and run into issues. – sradomski Mar 06 '14 at 12:09
7

Android 4.1 adds native Bonjour support (looks like its implemented via mDNSResponder) for applications. The high-level API seems to be called Network Service Discovery but appears to be Bonjour underneath. There also seems to be a lower-level API exposed via android.net.wifi.p2p.WifiP2pManager.

While it doesn't seem to be used for system-wide DNS lookups (e.g. I can't simply browse to http://machine.local via Chrome) it appears that this would be the way to do zeroconf/Bonjour lookups for native Android apps going forward.

natevw
  • 16,807
  • 8
  • 66
  • 90
  • 5
    Unfortunately, the native API does not allow access to the TXT record, which is severely limiting - https://code.google.com/p/android/issues/detail?id=136099 – Nick Dowell Jul 03 '15 at 14:46
3

Have you explicitly acquired the multicast lock so that you can receive the multicast packets?

AndroidManifest.xml:
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />

// Networking code:
WifiManager wifi = (WifiManager)getSystemService(Context.WIFI_SERVICE);
MulticastLock lock = wifi.createMulticastLock("mylock");
lock.acquire();

According to that Android Issue thread it looks like 2.0.1 doesn't have the fix. Perhaps you should transition to a later release?

smountcastle
  • 620
  • 5
  • 14
3

If you haven't seen it already, I suggest checking out this project on github (disclaimer - I'm not the author): https://github.com/twitwi/AndroidDnssdDemo

It is a sample project that pretty much shows how to get everything up and running. It also includes a custom jmdns.jar that solves some issues I was having with the out-of-the-box jmdns.jar having a duplicate class file.

svoisen
  • 3,292
  • 1
  • 18
  • 8