Android NSD onServiceFound() не вызывается
Впервые пытаюсь сделать IP Discovery в Android. Я использовал http://developer.android.com/training/connect-devices-wirelessly/nsd.html и написал код. Я не регистрирую устройство, просто обнаруживаю Услуги в сети. Когда я запускаю проект в эмуляторе или устройстве, вызывается 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);
}
}
2 ответа
Со страницы документации NdsManager:
В настоящее время API поддерживает обнаружение службы на основе DNS, и в настоящее время обнаружение ограничено локальной сетью через многоадресную DNS.
С этой страницы документации эмулятора ограничений локальной сети:
В настоящее время эмулятор не поддерживает IGMP или многоадресную рассылку.
Надеюсь, что это поможет вам
Вероятно, из-за возраста этого поста, я надеюсь, что вы уже нашли решение.
Если нет, то мой опыт показывает, что эмулятор Android (уровень API 25) не обеспечивает полный сетевой стек, а обнаружение службы через NSD не работает.
Я переключился на отладку на реальном устройстве (например, на Android-телевизоре или планшете), а затем все мои настройки, подобные NSD/Bonjour, работали. Были вызваны методы DiscoveryListener и ResolveListener, и были получены IP и порт (в моем случае).
После нескольких часов работы с Android NSD я обнаружил, что эта библиотека не работает с маршрутизаторами, которые не поддерживают многоадресную рассылку. Хотя другие ответы могут быть правильными, это также может быть причиной вашей проблемы. Возможные решения: включите Multicast на вашем маршрутизаторе, если это возможно, или используйте другую сетевую библиотеку.
Класс Network Service Discovery Manager предоставляет API для обнаружения служб в сети. Это будет работать, когда ваше устройство подключено к той же сети WIFI, что и устройство, предоставляющее услугу. Надеюсь это поможет!! Удачного кодирования!