Android NSD onServiceFound() не вызывается

Первый раз пытаюсь сделать IP Discovery в Android. Я использовал http://developer.android.com/training/connect-devices-wireless/nsd.html#discover и написал код. Я не регистрирую устройство, просто обнаруживаю службы в сети. Когда я запускаю проект в эмуляторе или устройстве, вызывается onDiscoveryStarted(), но onServiceFound() никогда не вызывается. Пожалуйста, найдите мой код ниже. Любой вклад очень ценится. Спасибо!

public class MainActivity extends AppCompatActivity {

    private Button discoverButton;

    Context mContext;

    NsdManager mNsdManager;
    NsdManager.ResolveListener mResolveListener;
    NsdManager.DiscoveryListener mDiscoveryListener;
    NsdManager.RegistrationListener mRegistrationListener;

    public static final String SERVICE_TYPE = "_http._tcp.";
    public static final String TAG = "MyApp_MAIN_CLIENT";
    public String mServiceName = "MyApp";

    /*
    * public static final String SERVICE_TYPE = "_http._tcp.";
    public static final String TAG = "NsdHelper";
    public String mServiceName = "NsdChat";
    * */

    NsdServiceInfo mService;
    private Handler mUpdateHandler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mNsdManager = (NsdManager) this.getSystemService(Context.NSD_SERVICE);
        discoverButton = (Button) findViewById(R.id.netButton);
        discoverButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(android.view.View v) {
                initializeDiscoveryListener();
                initializeResolveListener();
                discoverServices();

            }
        });

    }

    public void discoverServices() {
        mNsdManager.discoverServices(
                SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener);
    }


    public void initializeDiscoveryListener() {

        // Instantiate a new DiscoveryListener
        mDiscoveryListener = new NsdManager.DiscoveryListener() {

            //  Called as soon as service discovery begins.
            @Override
            public void onDiscoveryStarted(String regType) {
                Log.d(TAG, "Service discovery started");
            }

            @Override
            public void onServiceFound(NsdServiceInfo service) {
                // A service was found!  Do something with it.
                Log.d(TAG, "Service discovery success" + service);
                if (!service.getServiceType().equals(SERVICE_TYPE)) {
                    // Service type is the string containing the protocol and
                    // transport layer for this service.
                    Log.d(TAG, "Unknown Service Type: " + service.getServiceType());
                } /*else if (service.getServiceName().equals(mServiceName)) {
                    // The name of the service tells the user what they'd be
                    // connecting to. It could be "Bob's Chat App".
                    Log.d(TAG, "Same machine: " + mServiceName);
                }
                //else if (service.getServiceName().contains("NsdChat")){*/
                else{
                    mNsdManager.resolveService(service, mResolveListener);
                }
            }

            @Override
            public void onServiceLost(NsdServiceInfo service) {
                // When the network service is no longer available.
                // Internal bookkeeping code goes here.
                Log.e(TAG, "service lost" + service);
            }

            @Override
            public void onDiscoveryStopped(String serviceType) {
                Log.i(TAG, "Discovery stopped: " + serviceType);
            }

            @Override
            public void onStartDiscoveryFailed(String serviceType, int errorCode) {
                Log.e(TAG, "Discovery failed: Error code:" + errorCode);
                mNsdManager.stopServiceDiscovery(this);
            }

            @Override
            public void onStopDiscoveryFailed(String serviceType, int errorCode) {
                Log.e(TAG, "Discovery failed: Error code:" + errorCode);
                mNsdManager.stopServiceDiscovery(this);
            }
        };
    }// end of initializeListener()


    public void initializeResolveListener() {
        mResolveListener = new NsdManager.ResolveListener() {

            @Override
            public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {
                Log.e(TAG, "Resolve failed" + errorCode);
            }

            @Override
            public void onServiceResolved(NsdServiceInfo serviceInfo) {
                Log.e(TAG, "Resolve Succeeded. " + serviceInfo);

                if (serviceInfo.getServiceName().equals(mServiceName)) {
                    Log.d(TAG, "Same IP.");
                    return;
                }
                mService = serviceInfo;
                int port = mService.getPort();
                InetAddress host = mService.getHost();
                Log.d(TAG,host.toString());
            }
        };
    }//end of initializeResolveListener


    @Override
    protected void onPause() {
        super.onPause();
        stopDiscovery();
        tearDown();

    }

    @Override
    protected void onResume() {
        super.onResume();
        discoverServices();
    }

    @Override
    protected void onDestroy() {
        tearDown();
        super.onDestroy();
    }

    public void stopDiscovery() {
        mNsdManager.stopServiceDiscovery(mDiscoveryListener);
    }


    public void tearDown() {
        mNsdManager.unregisterService(mRegistrationListener);
    }
}

person pws35    schedule 22.04.2016    source источник
comment
Я не регистрирую устройство, а только обнаруживаю сервисы в сети. Вот в чем причина. Вы не можете обнаружить услугу, которая не была зарегистрирована. Одно устройство должно зарегистрировать службу, которую обнаружат другие устройства... (Совет относительно примера NSD: не регистрируйте и не обнаруживайте службу на одном устройстве)   -  person Onik    schedule 23.04.2016
comment
В документации Android NSD конкретно указано, что шаг «Регистрация» является необязательным. Если вы не хотите регистрировать свое устройство, перейдите к шагу 2: Обнаружение других служб   -  person pws35    schedule 23.04.2016
comment
Попробуйте удалить последнюю точку из _http._tcp. -> _http._tcp;   -  person Dmitry    schedule 25.10.2016


Ответы (4)


На странице документации NdsManager:

API в настоящее время поддерживает обнаружение службы на основе DNS, и обнаружение в настоящее время ограничено локальной сетью через многоадресную DNS.

На этой странице документации эмулятора ограничений локальной сети:

В настоящее время эмулятор не поддерживает IGMP или многоадресную рассылку.

Надеюсь, что это поможет вам

person sourcerebels    schedule 25.10.2017

Вероятно, из-за возраста этого поста, надеюсь, вы уже нашли решение.

Если нет, то, по моему опыту, эмулятор Android (уровень API 25) не предоставляет полный сетевой стек, и обнаружение службы через NSD не работает.

Я переключился на отладку на реальном устройстве (таком как Android TV или планшет), и тогда вся моя установка, похожая на NSD/Bonjour, заработала. Были вызваны методы DiscoveryListener и ResolveListener, и были получены IP и порт (в моем случае).

person Rutger van Dijk    schedule 16.03.2017

После нескольких часов работы с Android NSD я обнаружил, что эта библиотека не работает с маршрутизаторами, не поддерживающими Multicast. Хотя другие ответы могут быть правильными, это также может быть причиной вашей проблемы. Возможные решения: по возможности включите Multicast на роутере или используйте другую сетевую библиотеку.

person M Nijzink    schedule 06.08.2019

Класс Network Service Discovery Manager предоставляет API для обнаружения служб в сети. Это будет работать, когда ваше устройство подключено к той же сети WIFI, что и устройство, предоставляющее услугу. Надеюсь это поможет!! Удачного кодирования!!

person Rajan    schedule 23.05.2019