2016-04-15 12 views
1

私は、同じWi-Fiネットワーク上で同じサービスを実行しているピアを見つけて接続するために、NSDをアプリケーションで使用しようとしています。Androidでネットワークサービスディスカバリ(NSD)を使用しているサービスを検出できません

[コードを参照] Iは、HostActivity.javaGuestActivity.javaを実行いずれかを実行して一つのデバイスを有します。ホストのフローティングボタンをクリックすると、ポート9000(現在はプリセット)にサービスが登録され、ゲストでそのポートをクリックすると、サービスディスカバリの実行が開始されます。どちらも同じWi-Fiネットワークに接続されています。私のlogcatで

、私は正常に動作HostActivity.javaからその登録を観察する - 私はNsdHelper.javaから必要なログメッセージを取得します。ただし、GuestActivity.javaを実行すると、「Service Discovery started」がログに記録され、ネットワーク上に存在するサービスに解決されることはありません。

私は間違っていますか?助けてください。

関連するコード -

HostActivity.java

NsdHelper mNsdHelper; 

public static final String TAG = "ABC"; 
private final int ABC_PORT = 9000; 


@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_shared_list); 


    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
    setSupportActionBar(toolbar); 


    mNsdHelper = new NsdHelper(this); 

    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); 
    fab.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      Snackbar.make(view, "Started Registration", Snackbar.LENGTH_LONG) 
        .setAction("CLOSE", null).show(); 
      mNsdHelper.initializeNsd(); 
      mNsdHelper.registerService(ABC_PORT); 
      Snackbar.make(view, "Completed Registration", Snackbar.LENGTH_LONG) 
        .setAction("Action", null).show(); 

     } 
    }); 
} 

@Override 
protected void onPause() { 
    super.onPause(); 
} 

@Override 
protected void onResume() { 
    super.onResume(); 
    if (mNsdHelper != null) { 
     mNsdHelper.initializeNsd(); 
     mNsdHelper.registerService(ABC_PORT); 
    } 
} 

@Override 
protected void onDestroy() { 
    mNsdHelper.tearDown(); 
    super.onDestroy(); 
} 

GuestActivity.java

NsdHelper mNsdHelper; 

public static final String TAG = "ABC"; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_shared_list); 

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
    setSupportActionBar(toolbar); 

    mNsdHelper = new NsdHelper(this); 

    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); 
    fab.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      Snackbar.make(view, "Searching for available services", Snackbar.LENGTH_LONG) 
        .setAction("Action", null).show(); 
      mNsdHelper.initializeNsd(); 
      mNsdHelper.discoverServices(); 
     } 
    }); 
} 

@Override 
protected void onPause() { 
    super.onPause(); 
} 

@Override 
protected void onResume() { 
    super.onResume(); 
    if(mNsdHelper != null) { 
     mNsdHelper.initializeNsd(); 
     mNsdHelper.discoverServices(); 
    } 
} 

@Override 
protected void onDestroy() { 
    mNsdHelper.tearDown(); 
    super.onDestroy(); 
} 

NsdHelper.java - これは、すべてのNSDの実装の詳細が含まれています

public class NsdHelper { 
    Context mContext; 

    NsdManager mNsdManager; 
    NsdManager.ResolveListener mResolveListener; 
    NsdManager.DiscoveryListener mDiscoveryListener; 
    NsdManager.RegistrationListener mRegistrationListener; 

    private static final String SERVICE_TYPE = "_http._tcp."; 

    private static final String TAG = "NsdHelper"; 
    private String mServiceName = "ABC"; 

    // First step : register a NsdServiceInfo object to advertise your service 
    NsdServiceInfo mService; 

    public NsdHelper(Context context) { 
    mContext = context; 
    mNsdManager = (NsdManager) context.getSystemService(Context.NSD_SERVICE); 
} 


public void initializeNsd() { 
    initializeRegistrationListener(); 
    initializeDiscoveryListener(); 
    initializeResolveListener(); 

} 


// Check success of service registration 
public void initializeRegistrationListener() { 
    mRegistrationListener = new NsdManager.RegistrationListener() { 

     @Override 
     public void onServiceRegistered(NsdServiceInfo nsdServiceInfo) { 
      mServiceName = nsdServiceInfo.getServiceName(); 
      Log.d(TAG, "Registered name : " + mServiceName); 
     } 

     @Override 
     public void onRegistrationFailed(NsdServiceInfo nsdServiceInfo, int arg1) { 
      Log.d(TAG, "Registration Failed"); 
     } 

     @Override 
     public void onServiceUnregistered(NsdServiceInfo nsdServiceInfo) { 
      Log.d(TAG, "Unregistered"); 
     } 

     @Override 
     public void onUnregistrationFailed(NsdServiceInfo serviceInfo, int errorCode) { 
     } 

    }; 
} 

public void registerService(int port) { 
    NsdServiceInfo serviceInfo = new NsdServiceInfo(); 
    serviceInfo.setPort(port); 
    serviceInfo.setServiceName(mServiceName); 
    serviceInfo.setServiceType(SERVICE_TYPE); 

    mNsdManager.registerService(
      serviceInfo, NsdManager.PROTOCOL_DNS_SD, mRegistrationListener); 

} 

// To discover services of the type you're looking for on the network 
public void initializeDiscoveryListener() { 
    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 : " + service); 
      Log.d(TAG, "Host = "+ service.getServiceName()); 
      Log.d(TAG, "port = " + String.valueOf(service.getPort())); 

      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)){ 
       mNsdManager.resolveService(service, mResolveListener); 
      } 
     } 

     @Override 
     public void onServiceLost(NsdServiceInfo service) { 
      Log.e(TAG, "service lost" + service); 
      if (mService == service) { 
       mService = null; 
       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); 
     } 
    }; 
} 

public void discoverServices() { 
    mNsdManager.discoverServices(
      SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener); 
} 


// Connection handshake 
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(); 
     } 
    }; 
} 

public void stopDiscovery() { 
    if (mNsdManager != null) { 
     mNsdManager.stopServiceDiscovery(mDiscoveryListener); 
    } 
} 

public NsdServiceInfo getChosenServiceInfo() { 
    return mService; 
} 

public void tearDown() { 
    if (mNsdManager != null) { 
     if (mRegistrationListener != null) { 
      mNsdManager.unregisterService(mRegistrationListener); 
     } 
     if (mDiscoveryListener != null) { 
      mNsdManager.stopServiceDiscovery(mDiscoveryListener); 
     } 
    } 
} 

}

+0

私はNSDでプレイしたことがないので、このコードに関しては何の推薦もありません。このような場合には、既存の作業コードを見つけようとしていますが、必要な作業を行うまでそのコードをゆっくりと変更します。私は最終的に私が物事を壊している場所を見つけ出すか、作業コードを取得します。 :-) GoogleにはNSDのサンプルがあるかもしれないが、最近のAndroidカンファレンス(droidcon.it 2016?)にNSDに関するプレゼンテーションがあったことを思い出しているようだ。 – CommonsWare

+0

コアのNSDコードの大部分(すべて?)は、基本的にhttp://developer.android.com/training/connect-devices-wirelessly/nsd.htmlからそのまま受け継がれています。 Google自体のベースは機能しません。私はまた、(ここ2年前から)ここで働くと主張する同様のコードを見てきました - http://www.jayrambhia.com/blog/android-wireless-connection-1/しかし、それはどちらも成立しません。私は同じことについてdroidconのプレゼンテーションを探します - 私は何かを見つけることを望みましょう。先端に感謝します。 – user1649740

+0

public void onServiceFound(NsdServiceInfoサービス)が呼び出されている場合、少なくともあなたのログステートメントが表示されます。私はいくつかの一般的なアンドロイドタブレットで同様のプログラムを実行しています。サービスが見つからない場合は、両方のデバイスをシャットダウンしてから再度オンにする必要があります。クイックブートの再起動は機能しません。これは回避策ですが、私はこれを行うためのより良い方法を公開しています。 –

答えて

0

あなたは、Androidデベロッパーサイト上のコードサンプルを追ったようだ、と私たちをブロック2つのミスがあります:public void onServiceFound(NsdServiceInfo service)方法、サービスをチェックするためのコードで

  1. は、名前が正しくありません。私の理解では、同じネットワーク内の他のデバイスも同じサービス命名を使用する可能性がありますので、if (service.getServiceName().equals(mServiceName))コードブロックを削除してください。
  2. public void onServiceResolved(NsdServiceInfo serviceInfo)コードブロックでも同じことが起こります。 if (serviceInfo.getServiceName().equals(mServiceName))コードブロックを削除してください。
+0

私はあなたのコメントに同意しますが、ここでは、ネットワークに複数のデバイスが接続されていても "onServiceFound(NsdServiceInfoサービス)"メソッドが呼び出されないという問題があります。 SERVICE_TYPEを使用していますが、 "_http._tcp"です。 – sandeepmaaram

関連する問題