serviceRemoved is not called while discovering the devices

181 views Asked by At

I am working on a project that needs to discover all the devices in the same wi-fi network. For implementing this I have used Jmdns library.

It is giving me the list of devices that are registered into the current network, but when the device gets unregistered it should call serviceRemoved method of ServiceListener. However, it is not calling the serviceRemoved when the device is unregistered.

Here is my code.:

public class LanService {
    private static LanService instance = new LanService();
    private final String TYPE = "_sample._tcp.local.";
    private JmDNS jmdns = null;
    private ServiceInfo serviceInfo;
    private WifiManager.MulticastLock lock;
    private ServiceListener listener;

    public static LanService getInstance() {
        return instance;
    }

    public void startDiscovery() {
        WifiManager wifi = (WifiManager) AppBase.getAppContext().getSystemService(Context.WIFI_SERVICE);
        if (wifi.isWifiEnabled()) {
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    Thread startDiscoveryThread = new Thread(new Runnable() {
                        @Override
                        public void run() {
                            if (serviceInfo != null) {
                                stopScan();
                            }
                            setUp();
                        }
                    });
                    startDiscoveryThread.start();
                }
            }, 2000);
        }
    }

    @Override
    public void stopDiscovery() {
        Thread stopDiscoveryThread = new Thread(new Runnable() {
            @Override
            public void run() {
                stopScan();
            }
        });
        stopDiscoveryThread.start();

    }

    private void setUp() {
        try {
            WifiManager wifi = (WifiManager) AppBase.getAppContext().getSystemService(Context.WIFI_SERVICE);
            if (!wifi.isWifiEnabled()) {
                wifi.setWifiEnabled(true);
            }

            // get the device ip address
            final InetAddress deviceIpAddress = getLocalIpAddress();
            if (deviceIpAddress != null) {
                lock = wifi.createMulticastLock(getClass().getName());
                lock.setReferenceCounted(true);
                lock.acquire();
                jmdns = JmDNS.create(deviceIpAddress);

                serviceInfo = ServiceInfo.create(TYPE, Build.MODEL, 3129, "plain test service from android");
                jmdns.registerService(serviceInfo);

                jmdns.addServiceListener(TYPE, listener = new ServiceListener() {

                    @Override
                    public void serviceResolved(ServiceEvent ev) {
                        Log.d(TAG, "Service Resolved : " + ev.getInfo().getQualifiedName() + " ipAddr : " + ev.getInfo().getInetAddresses()[0]);
                    }

                    @Override
                    public void serviceRemoved(ServiceEvent ev) {
                        Log.d(TAG, "Service Removed : " + ev.getInfo().getQualifiedName() + " ipAddr : " + ev.getInfo().getInetAddresses()[0]);
                    }

                    @Override
                    public void serviceAdded(ServiceEvent ev) {
                        try {
                            // Required to force serviceResolved to be called again (after the first search)
                            Log.d(TAG, "Service Added : " + ev.getInfo().getQualifiedName());
                            jmdns.requestServiceInfo(ev.getType(), ev.getName(), 1000);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                });
            }
        } catch (IOException ex) {
            ex.printStackTrace();
            Log.e(TAG, ex.getMessage(), ex);
        }
        Log.i(TAG, "Started ZeroConf probe....");
    }

    private void stopScan() {
        try {
            if (jmdns != null) {
                Log.i(TAG, "Stopping ZeroConf probe....");
                jmdns.removeServiceListener(TYPE, listener);
                jmdns.unregisterService(serviceInfo);
                jmdns.unregisterAllServices();
                jmdns.close();
                jmdns = null;
            }
            if (lock != null) {
                Log.i(TAG, "Releasing Mutlicast Lock...");
                if (lock.isHeld())
                    lock.release();
                lock = null;
            }
        } catch (Exception ex) {
            Log.e(TAG, ex.getMessage(), ex);
        }
    }
}

Why is serviceRemoved not getting invoked when the device is unregistered from the network? Any suggestions are appreciated .

1

There are 1 answers

2
Konstantinos Michael On

Why do you open a thread inside the runnable of the handler? The Handler runs the runnable on a separate thread. What you do is:

-The handler runs the runnable on a thread and you open another thread and do your stuff. Maybe that is your problem.

Instead of this:

new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    Thread startDiscoveryThread = new Thread(new Runnable() {
                        @Override
                        public void run() {
                            if (serviceInfo != null) {
                                stopScan();
                            }
                            setUp();
                        }
                    });
                    startDiscoveryThread.start();
                }
            }, 2000);

Try this:

new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                            if (serviceInfo != null) {
                                stopScan();
                            }
                       setUp();
                    }

            }, 2000);