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 .
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:
Try this: