发现设备时不调用serviceRemoved

时间:2015-06-15 12:39:45

标签: android jmdns

我正在开发一个需要发现同一个Wi-Fi网络中所有设备的项目。为了实现这一点,我使用了Jmdns库。

它向我提供了注册到当前网络的设备列表,但是当设备取消注册时,它应该调用serviceRemoved ServiceListener方法。但是,当设备未注册时,它不会调用serviceRemoved

这是我的代码:

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);
        }
    }
}

为什么在从网络注销设备时不会调用serviceRemoved?任何建议表示赞赏。

1 个答案:

答案 0 :(得分:0)

为什么要在处理程序的runnable中打开一个线程? Handler在单独的线程上运行runnable。你做的是:

- 处理程序在一个线程上运行runnable,然后打开另一个线程并执行你的操作。也许那是你的问题。

而不是:

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);

试试这个:

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

            }, 2000);