The Whizzo Blog

Android, JmDNS and Wi-Fi multicast packets

For the current project I'm working on, I chose to use the excellent JmDNS library to facilitate Android device service discovery on the local Wifi network. Just be sure to use version 3.4.0 or greater since it fixes some issues with using JDK methods that don't exist on Android (e.g. certain IOException constructors).

During the course of development, I successfully tested everything between my Mac desktop and laptop. However, the same code on the Android device didn't work properly. The Mac clients on the network could see the Android device's broadcasted packets but the device couldn't see anyone else's. After the requisite investigation to make sure it wasn't a bug lurking in my code, I had to resort to Googling around for possible solutions.

As it turns out, the Android Wifi stack ignores multicast packets not explicitly destined for the device itself. Given the nature of how JmDNS works (Zeroconf to be more precise), this prevented the device from discovering any services on the network but still allowed other clients to discover its services. To solve the problem, one must use the Android SDK to obtain a multicast lock. For example:

WifiManager wm = (WifiManager)getSystemService(Context.WIFI_SERVICE);
WifiManager.MulticastLock multicastLock = wm.createMulticastLock("mydebuginfo");
multicastLock.acquire();

This alone causes a permission error since the application isn't allowed to alter the multicast state by default. Adding the following to the application manifest makes quick work of that problem:

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

And there you have it... your device(s) should now successfully send and receive JmDNS multicast packets on a local Wifi network.

Posted on Mar 1, 2011 by Dan.