31

Android Native Service Discovery を使用してアプリケーションを実行しようとしていますが、アプリケーションを実行すると、ネットワークからすべてのサービスが検出されないことがあります。4 つの Galaxy nexus を使用してhttps://github.com/joeluchoa/nsdからコードを実行していますが、ほとんどの場合、それぞれが異なる数のサービスを同時に検出します。

基本的に、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);

次に、NsdManager の registerService メソッドを使用して公開します。

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);

サービスを発見するには、NsdManager からメソッド discoverServices を使用します。

mNsdManager.discoverServices(SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD,
        mDiscoveryListener);

次のように mDiscoveryListener を使用します。

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);
    }
};

私は何か間違ったことをしていますか?誰かがこれに対する解決策または回避策を知っていますか?

4

6 に答える 6

9

接続されたネットワークのすべてのサービスを検出するには、検出するサービス タイプを変更するだけです。

public static final String SERVICE_TYPE = "_services._dns-sd._udp";
于 2018-12-05T10:56:08.737 に答える
1

私は、Android の NSD 実装全体が少し不安定であるに違いないと考える傾向があります。また、ライフサイクルを示すための単純なアクティビティ (ソケットは開かれていません) もあり、動作する場合と動作しない場合があります。私は単にそれを理解していません。誰かが洞察を持っている場合のアクティビティは次のとおりです。

https://github.com/mholzel/Dump/blob/master/NetworkServiceDiscoveryViaWifi.java

一方、Wifi Direct ベースの NSD は、私にとって非常に信頼できるようです。

https://github.com/mholzel/Dump/blob/master/NetworkServiceDiscoveryViaWifiDirect.java

これらのアクティビティにはリソースがないため、適切な権限でアクティビティをマニフェストに追加するだけです。

于 2016-11-02T10:57:36.437 に答える
1

残念ながら、実装にはまだバグがあり、サービスが失われる可能性があります。複数の Android デバイスと 1 台の MacBook で数日間テストしましたが、常に機能するとは限りません。Android バグ トラッカーのバグ レポートに関する調査結果を文書化しました: https://code.google.com/p/android/issues/detail?id=178080

于 2015-12-27T15:50:22.343 に答える
1

答えには少し遅れるかもしれませんが、開発者サイトで Android 用の NSD の良い解決策を見つけました。いくつかの変更を加えましたが、完全に正常に動作します。

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);
}
}

これが役立つことを願っています

于 2017-10-31T05:40:06.267 に答える