1

I've had some difficulty getting JmDNS to work with my Android AVD. I've created 3 applications. An Android application which registers a ServiceListener and logs any activity, A Java application which does the same as the android application, and another Java application which registers a service. The Java listener application will pick up on the other Java application, however the android application will not. I've also tried running two AVD simultaneously to see if they'd pick up on each other and they don't. I should also mention that I have permissions for INTERNET and CHANGE_WIFI_MULSTICAST_STATE enabled. Here's my code:

Android Application:

public class BonjourActivity extends Activity {

    // Multicast
    private WifiManager wifi;
    private MulticastLock lock;
    private JmDNS jmdns;
    private String type = "_im._tcp.local.";
    private ServiceListener listener;
    private ServiceInfo serviceInfo;

    // On Create
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // Multicast
        wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
        lock = wifi.createMulticastLock("");
        lock.setReferenceCounted(true);
        lock.acquire();

        // JmDNS
        new AsyncTask<Object, Object, Object>(){
            @Override
            protected Object doInBackground(Object... params) {
                // Create JmDNS
                try {
                    jmdns = JmDNS.create();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                return null;
            }
             protected void onPostExecute(Object result) {
                 // Add Listener
                 jmdns.addServiceListener(type, listener = new ServiceListener(){
                        @Override
                        public void serviceAdded(ServiceEvent ev) {
                            jmdns.requestServiceInfo(ev.getType(), ev.getName(), 1);
                        }
                        @Override
                        public void serviceRemoved(ServiceEvent ev) {
                            Log.d("Service", "Service Removed: " + ev.getName());
                        }
                        @Override
                        public void serviceResolved(ServiceEvent ev) {
                            Log.d("Service", "Service Resolved: " + ev.getInfo().getURL());
                        }
                    });
             }
        }.execute(); 
    }

    // On Destroy
    public void onDestroy(){
        // Release Lock
        if (lock != null){
            lock.release();
        }
        // Close JmDNS
        if (jmdns != null){
            jmdns.removeServiceListener(type, listener);
            try {
                jmdns.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        super.onDestroy();
    }
}

Java Listener Application:

public class Listener {

    private static JmDNS jmdns;
    private static String type = "_im._tcp.local.";
    private static ServiceListener serviceListener;
    private static ServiceInfo serviceInfo;

    // Main
    public static void main(String args[]){

        try {
            jmdns = JmDNS.create();
            jmdns.addServiceListener(type, serviceListener = new ServiceListener(){
                @Override
                public void serviceAdded(ServiceEvent ev) {
                    System.out.println("Service Added: " + ev.getName());
                    jmdns.requestServiceInfo(ev.getType(), ev.getName(), 1);
                }
                @Override
                public void serviceRemoved(ServiceEvent ev) {
                    System.out.println("Service Removed: " + ev.getName());
                }
                @Override
                public void serviceResolved(ServiceEvent ev) {
                    System.out.println("Service Resolved: " + ev.getInfo().getURL());
                }
            });
            System.out.println("Listener Added");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}

Java Sender Application:

public class Sender {

    private static JmDNS jmdns;
    private static String type = "_im._tcp.local.";
    private static ServiceListener serviceListener;
    private static ServiceInfo serviceInfo;

    // Main
    public static void main(String args[]){

        try {
            jmdns = JmDNS.create();
            serviceInfo = ServiceInfo.create(type, "Test IM Service", 55555, "Instant messaging test service");
            jmdns.registerService(serviceInfo);
            System.out.println("Sender: Service Created");
            new Timer().schedule(new TimerTask(){
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    System.out.println("Closing..");
                    jmdns.unregisterAllServices();
                    try {
                        jmdns.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    System.exit(0);
                }
            }, 10000);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}

In Addition, LogCat gives me a few errors when I attempt to run the application:

NetworkManagementSocketTagger setKernelCountSet(10009,0) failed with errno -2

WifiStateMachine Error! unhandled message{ what=131157 when=-1ms }

Might anyone know why the android application is unable to pick up on JmDNS services generated by other applications?

John
  • 11
  • 2
  • Move jmdns.addServiceListener(... code block from onPostExecute() to doInBackground(), also better not to create your listener as inline anonymous class. – yorkw Mar 28 '12 at 01:48

1 Answers1

1

Just a little notice, The virtual device running in the emulator is not in the same network as the computer. Service discovery may not work. My implementation of jmdns does not work in the emulator. Try it on a real device. And go to http://home.heeere.com/tech-androidjmdns.html for more details.

RaphMclee
  • 1,623
  • 13
  • 16