Android NSD pas de découvrir tous les services
j'essaie d'exécuter une application en utilisant Android Native Service Discovery mais parfois quand j'exécute l'application, il ne découvre pas tous les services de mon réseau. J'utilise le code de https://github.com/joeluchoa/nsd en utilisant quatre Galaxy nexus et la plupart du temps chacun d'eux découvre un nombre différent de services en même temps.
en gros je dirige un service avec 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);
puis je le publie en utilisant la méthode registerService from 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);
pour découvrir les services que j'utilise la méthode discoverServices de NsdManager:
mNsdManager.discoverServices(SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD,
mDiscoveryListener);
avec mDiscoveryListener comme suit:
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);
}
};
je fais quelque chose de mal? Quelqu'un connais une solution ou une solution pour cela?
4 réponses
j'ai eu le même problème, réinstallez aidé. Essayez de l'utiliser:)
j'ai bien peur qu'il y ait encore des bugs dans l'implémentation qui font qu'il manque des services. J'ai fait quelques jours de tests avec plusieurs appareils Android et un MacBook, et ça ne fonctionne pas tout le temps. J'ai documenté mes conclusions sur un rapport de bogue dans L'Android bug tracker: https://code.google.com/p/android/issues/detail?id=178080
j'ai tendance à penser l'ensemble de la NSD mise en œuvre dans Android doit être un peu capricieux. J'ai aussi une activité simple pour montrer le cycle de vie (pas de Sockets ouverts), et parfois ça marche, et parfois ça ne marche pas. Je n'ai tout simplement pas l'obtenir. Voici L'activité si quelqu'un a un aperçu:
https://github.com/mholzel/Dump/blob/master/NetworkServiceDiscoveryViaWifi.java
D'autre part, Wifi Direct basé sur NSD semble être très fiable pour moi:
https://github.com/mholzel/Dump/blob/master/NetworkServiceDiscoveryViaWifiDirect.java
notez qu'aucune de ces activités n'a de ressources, donc il suffit d'ajouter les activités à votre manifeste avec les permissions appropriées.
il peut être un peu tard pour la réponse, mais j'ai trouvé une bonne solution pour NSD pour android donner sur leur site de développement. J'ai fait quelques modification et il fonctionne parfaitement 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);
}
}
Espérons que cette aide