Android NSD onServiceFound()没有被调用

时间:2016-04-22 14:51:28

标签: android nsd

第一次尝试在Android中进行IP发现。我使用了http://developer.android.com/training/connect-devices-wirelessly/nsd.html#discover并编写了代码。我没有注册设备,只是在网络中发现服务。当我在模拟器或设备中运行项目时,会调用onDiscoveryStarted(),但永远不会调用onServiceFound()。请在下面找到我的代码。任何输入都非常感谢。谢谢!

public class MainActivity extends AppCompatActivity {

    private Button discoverButton;

    Context mContext;

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

    public static final String SERVICE_TYPE = "_http._tcp.";
    public static final String TAG = "MyApp_MAIN_CLIENT";
    public String mServiceName = "MyApp";

    /*
    * public static final String SERVICE_TYPE = "_http._tcp.";
    public static final String TAG = "NsdHelper";
    public String mServiceName = "NsdChat";
    * */

    NsdServiceInfo mService;
    private Handler mUpdateHandler;

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

        mNsdManager = (NsdManager) this.getSystemService(Context.NSD_SERVICE);
        discoverButton = (Button) findViewById(R.id.netButton);
        discoverButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(android.view.View v) {
                initializeDiscoveryListener();
                initializeResolveListener();
                discoverServices();

            }
        });

    }

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


    public void initializeDiscoveryListener() {

        // Instantiate a new DiscoveryListener
        mDiscoveryListener = new NsdManager.DiscoveryListener() {

            //  Called as soon as service discovery begins.
            @Override
            public void onDiscoveryStarted(String regType) {
                Log.d(TAG, "Service discovery started");
            }

            @Override
            public void onServiceFound(NsdServiceInfo service) {
                // A service was found!  Do something with it.
                Log.d(TAG, "Service discovery success" + service);
                if (!service.getServiceType().equals(SERVICE_TYPE)) {
                    // Service type is the string containing the protocol and
                    // transport layer for this service.
                    Log.d(TAG, "Unknown Service Type: " + service.getServiceType());
                } /*else if (service.getServiceName().equals(mServiceName)) {
                    // The name of the service tells the user what they'd be
                    // connecting to. It could be "Bob's Chat App".
                    Log.d(TAG, "Same machine: " + mServiceName);
                }
                //else if (service.getServiceName().contains("NsdChat")){*/
                else{
                    mNsdManager.resolveService(service, mResolveListener);
                }
            }

            @Override
            public void onServiceLost(NsdServiceInfo service) {
                // When the network service is no longer available.
                // Internal bookkeeping code goes here.
                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);
            }
        };
    }// end of initializeListener()


    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();
                Log.d(TAG,host.toString());
            }
        };
    }//end of initializeResolveListener


    @Override
    protected void onPause() {
        super.onPause();
        stopDiscovery();
        tearDown();

    }

    @Override
    protected void onResume() {
        super.onResume();
        discoverServices();
    }

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

    public void stopDiscovery() {
        mNsdManager.stopServiceDiscovery(mDiscoveryListener);
    }


    public void tearDown() {
        mNsdManager.unregisterService(mRegistrationListener);
    }
}

4 个答案:

答案 0 :(得分:2)

可能由于这篇文章的年龄,我希望你已经找到了解决方案。

如果没有,我的经验是Android模拟器(API级别25)不提供完整的网络堆栈,并且通过NSD的服务发现不起作用。

我切换到真实设备(如Android TV或平板电脑)上的调试,然后我的整个NSD / Bonjour式设置正常工作。调用了DiscoveryListener和ResolveListener的方法,并检索了IP和端口(在我的例子中)。

答案 1 :(得分:2)

来自NdsManager documentation page

  

API目前支持基于DNS的服务发现和发现   目前仅限于通过多播DNS的本地网络。

从此Local networking limitations emulator docs page

  

目前,模拟器不支持IGMP或组播。

希望这会对你有所帮助

答案 2 :(得分:0)

网络服务发现管理器类提供用于发现网络上服务的API。 当您的设备连接到与提供服务的设备相同的WIFI网络时,此方法将起作用。 希望这可以帮助!! 祝您编码愉快!

答案 3 :(得分:0)

使用Android NSD几个小时后,我发现此库不适用于不支持多播的路由器。尽管其他答案可能是正确的,但这也可能是您遇到问题的原因。可能的解决方案:如果可能,在路由器上启用“多播”,或使用其他网络库。