2016-04-22 6 views
2

Первый раз, пытаясь сделать IP Discovery в Android. Я использовал http://developer.android.com/training/connect-devices-wirelessly/nsd.html#discover и написал код. Я не регистрирую устройство, просто открывая службы в сети. Когда я запускаю проект в эмуляторе или устройстве, вызывается onDiscoveryStarted(), но onServiceFound() никогда не вызывается. Пожалуйста, найдите мой код ниже. Любой вход очень ценится. Благодаря!Android NSD 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); 
    } 
} 
+0

_ «Я не регистрируя устройство, просто Обретение услуги в сети» _. Вот в чем причина. Вы не можете обнаружить службу, которая не была зарегистрирована. Одно устройство должно зарегистрировать услугу, которую обнаружат другие устройства ... (Совет, касающийся образца «NSD»: не регистрируйте и не обнаруживайте услугу на том же устройстве) – Onik

+0

Документация Android NSD специально говорит о том, что шаг «Регистрация» является необязательным , Если вы не хотите регистрировать свое устройство, перейдите к шагу 2: Обнаружение других служб – pws35

+0

Попробуйте удалить последнюю точку из «_http._tcp.». -> "_http._tcp"; – Dmitry

ответ

1

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

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

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

0

От NdsManager documentation page:

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

Из этого Local networking limitations emulator docs page:

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

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