7

第一次尝试在 Android 中进行 IP 发现。我使用了http://developer.android.com/training/connect-devices-wireless/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

4 回答 4

7

NdsManager 文档页面

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

从此本地网络限制模拟器文档页面

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

希望对你有帮助

于 2017-10-25T07:21:14.090 回答
3

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

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

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

于 2017-03-16T21:02:44.457 回答
1

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

于 2019-08-06T14:37:46.000 回答
-1

Network Service Discovery Manager 类提供 API 来发现网络上的服务。当您的设备连接到与提供服务的设备相同的 WIFI 网络时,这将起作用。希望这可以帮助!!编码快乐!!

于 2019-05-23T08:07:24.410 回答