example - Android NSD no descubre todos los servicios.
p2p android example (4)
Me temo que todavía hay errores en la implementación que hacen que se pierdan los servicios. He hecho un par de días de pruebas con múltiples dispositivos Android y un MacBook, y simplemente no funciona todo el tiempo. Documenté mis hallazgos en un informe de errores en el rastreador de errores de Android: https://code.google.com/p/android/issues/detail?id=178080
Estoy tratando de ejecutar una aplicación usando Android Native Service Discovery pero a veces cuando ejecuto la aplicación, no se detectan todos los servicios de mi red. Estoy ejecutando el código de https://github.com/joeluchoa/nsd usando cuatro galaxias nexus y la mayoría de las veces cada uno de ellos descubre diferentes servicios al mismo tiempo.
Básicamente ejecuto un servicio con un ServerSocket:
ServerSocket server = new ServerSocket(0);
Log.i(TAG, "IP " + server.getInetAddress()
+ ", running on port " + server.getLocalPort());
Intent intent = new Intent(MySocket.this,
MyPresence.class);
intent.putExtra("PORT", server.getLocalPort());
startService(intent);
Luego lo publico usando el método registerService de NsdManager:
NsdServiceInfo serviceInfo = new NsdServiceInfo();
serviceInfo.setServiceName(Build.SERIAL + "-" + new Date().getTime());
serviceInfo.setServiceType(SERVICE_TYPE);
serviceInfo.setPort(port);
mNsdManager.registerService(serviceInfo, NsdManager.PROTOCOL_DNS_SD,
mRegistrationListener);
Para descubrir los servicios, uso el método discoverServices de NsdManager:
mNsdManager.discoverServices(SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD,
mDiscoveryListener);
Con mDiscoveryListener de la siguiente manera:
mDiscoveryListener = new NsdManager.DiscoveryListener() {
@Override
public void onDiscoveryStarted(String regType) {
Log.d(TAG, "Service discovery started");
}
@Override
public void onServiceFound(NsdServiceInfo service) {
Log.d(TAG, "Service discovery success");
Log.d(TAG, String.format("%s %s %s %d",
service.getServiceName(), service.getServiceType(),
service.getHost(), service.getPort()));
if (!service.getServiceType().contains(SERVICE_TYPE)) {
Log.d(TAG,
"Unknown Service Type: " + service.getServiceType());
} else if (service.getServiceName().equals(mServiceName)) {
Log.d(TAG, "Same machine: " + mServiceName);
} else {
mNsdManager.resolveService(service, mResolveListener);
}
}
@Override
public void onServiceLost(NsdServiceInfo service) {
Log.e(TAG, "service lost" + service);
}
@Override
public void onDiscoveryStopped(String serviceType) {
Log.i(TAG, serviceType + " Discovery stopped: " + serviceType);
}
@Override
public void onStartDiscoveryFailed(String serviceType, int errorCode) {
Log.e(TAG, serviceType + " Discovery failed: Error code:"
+ errorCode);
mNsdManager.stopServiceDiscovery(this);
}
@Override
public void onStopDiscoveryFailed(String serviceType, int errorCode) {
Log.e(TAG, serviceType + " Discovery failed: Error code:"
+ errorCode);
mNsdManager.stopServiceDiscovery(this);
}
};
¿Estoy haciendo algo mal? ¿Alguien sabe una solución o una solución para esto?
Puede que sea un poco tarde para la respuesta, pero encontré una buena solución para NSD para Android en su sitio de desarrollador. Hice algunas modificaciones y funciona perfectamente bien.
public class NsdClient {
private Context mContext;
private NsdManager mNsdManager;
NsdManager.DiscoveryListener mDiscoveryListener;
//To find all the available networks SERVICE_TYPE = "_services._dns-sd._udp"
public static final String SERVICE_TYPE = "_hap._tcp.";
public static final String TAG = "NsdClient";
private static ArrayList<NsdServiceInfo> ServicesAvailable = new ArrayList<>();
public NsdClient(Context context) {
mContext = context;
mNsdManager = (NsdManager) context.getSystemService(Context.NSD_SERVICE);
}
public void initializeNsd() {
initializeDiscoveryListener();
}
public void initializeDiscoveryListener() {
mDiscoveryListener = new NsdManager.DiscoveryListener() {
@Override
public void onDiscoveryStarted(String regType) {
Log.d(TAG, "Service discovery started " + regType);
}
@Override
public void onServiceFound(NsdServiceInfo service) {
Log.d(TAG, "Service discovery success " + service);
AVAILABLE_NETWORKS.add(service);
if (!service.getServiceType().equals(SERVICE_TYPE)) {
Log.d(TAG, "Unknown Service Type: " + service.getServiceType());
} else if (service.getServiceName().equals(mServiceName)) {
Log.d(TAG, "Same Machine: " + mServiceName);
} else if (service.getServiceName().contains(mServiceName)) {
Log.d(TAG, "Resolving Services: " + service);
mNsdManager.resolveService(service, new initializeResolveListener());
}
}
@Override
public void onServiceLost(NsdServiceInfo service) {
Log.e(TAG, "service lost" + service);
if (ServicesAvailable.equals(service)) {
ServicesAvailable = null;
}
}
@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);
}
};
}
public class initializeResolveListener implements NsdManager.ResolveListener {
@Override
public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {
Log.e(TAG, "Resolve failed " + errorCode);
switch (errorCode) {
case NsdManager.FAILURE_ALREADY_ACTIVE:
Log.e(TAG, "FAILURE ALREADY ACTIVE");
mNsdManager.resolveService(serviceInfo, new initializeResolveListener());
break;
case NsdManager.FAILURE_INTERNAL_ERROR:
Log.e(TAG, "FAILURE_INTERNAL_ERROR");
break;
case NsdManager.FAILURE_MAX_LIMIT:
Log.e(TAG, "FAILURE_MAX_LIMIT");
break;
}
}
@Override
public void onServiceResolved(NsdServiceInfo serviceInfo) {
Log.e(TAG, "Resolve Succeeded. " + serviceInfo);
if (serviceInfo.getServiceName().equals(mServiceName)) {
Log.d(TAG, "Same IP.");
return;
}
}
}
public void stopDiscovery() {
mNsdManager.stopServiceDiscovery(mDiscoveryListener);
}
public List<NsdServiceInfo> getChosenServiceInfo() {
return ServicesAvailable;
}
public void discoverServices() {
mNsdManager.discoverServices(
SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener);
}
}
Espero que esto ayude
Tiendo a pensar que toda la implementación de NSD en Android debe ser un poco inestable. También tengo una Actividad simple solo para demostrar el ciclo de vida (no se abren Sockets), y algunas veces funciona, y otras veces no funciona. Simplemente no lo entiendo. Aquí está la actividad si alguien tiene alguna idea:
https://github.com/mholzel/Dump/blob/master/NetworkServiceDiscoveryViaWifi.java
Por otro lado, el NSD basado en Wifi Direct parece ser muy confiable para mí:
https://github.com/mholzel/Dump/blob/master/NetworkServiceDiscoveryViaWifiDirect.java
Tenga en cuenta que ninguna de estas Actividades tiene recursos, así que solo agregue las Actividades a su Manifiesto con los permisos adecuados.
Tuve el mismo problema, reinstalar ayudó. Tratar de usar:)