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?

29
demandé sur user1728985 2012-10-09 16:03:40

4 réponses

j'ai eu le même problème, réinstallez aidé. Essayez de l'utiliser:)

1
répondu Gerald Cunningham 2014-10-08 15:18:17

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

1
répondu Ulf Adams 2015-12-27 15:50:22

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.

1
répondu bremen_matt 2016-11-02 11:51:32

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

0
répondu Aarth Tandel 2017-10-31 05:40:06