如何通过DependencyService正确实现Xamarin NetworkServiceDiscovery?

时间:2017-09-30 15:13:30

标签: c# xamarin xamarin.android

我有一个Xamarin跨平台应用程序,并希望使用Android的NetworkServiceDiscovery API。

我尝试根据https://developer.android.com/training/connect-devices-wirelessly/nsd.html实施它 现在,我不确定我是否做得对,例如:android文档要求你创建一个这样的RegistrationListener:

机器人:

public void initializeRegistrationListener() {
    mRegistrationListener = new NsdManager.RegistrationListener() {

        @Override
        public void onServiceRegistered(NsdServiceInfo NsdServiceInfo) {
            // Save the service name.  Android may have changed it in order to
            // resolve a conflict, so update the name you initially requested
            // with the name Android actually used.
            mServiceName = NsdServiceInfo.getServiceName();
        }

        @Override
        public void onRegistrationFailed(NsdServiceInfo serviceInfo, int errorCode) {
            // Registration failed!  Put debugging code here to determine why.
        }

        @Override
        public void onServiceUnregistered(NsdServiceInfo arg0) {
            // Service has been unregistered.  This only happens when you call
            // NsdManager.unregisterService() and pass in this listener.
        }

        @Override
        public void onUnregistrationFailed(NsdServiceInfo serviceInfo, int errorCode) {
            // Unregistration failed.  Put debugging code here to determine why.
        }
    };
}

我在C#中重建了这个:

public class RegistrationListener : NsdManager.IRegistrationListener
    {
        public string serviceName;

        public void Dispose()
        {
            throw new NotImplementedException();
        }

        public IntPtr Handle { get; }

        public void OnRegistrationFailed(NsdServiceInfo serviceInfo, NsdFailure errorCode)
        {
            // Registration failed!  Put debugging code here to determine why.
        }

        public void OnServiceRegistered(NsdServiceInfo serviceInfo)
        {
            // Save the service name.  Android may have changed it in order to
            // resolve a conflict, so update the name you initially requested
            // with the name Android actually used.
            serviceName = serviceInfo.ServiceName;
        }

        public void OnServiceUnregistered(NsdServiceInfo serviceInfo)
        {
            // Service has been unregistered.  This only happens when you call
            // NsdManager.unregisterService() and pass in this listener.
        }

        public void OnUnregistrationFailed(NsdServiceInfo serviceInfo, NsdFailure errorCode)
        {
            // Unregistration failed.  Put debugging code here to determine why.
        }
    }

我以同样的方式实现了ResolveListener和DiscoveryListener。

然后我创建了一个Helper类,其中包含我想通过DependencyServices调用的函数:

public class NsdHelper
    {
        public static readonly string SERVICE_TYPE = "chatTest._tcp";

        public DiscoveryListener discoveryListener;
        public NsdManager nsdManager;

        public NsdServiceInfo nsdServiceInfo;
        public RegistrationListener registrationListener;
        public ResolveListener resolveListener;

        public string SERVICE_NAME { get; set; }

        public void InitializeNsd()
        {
            resolveListener = new ResolveListener();
            discoveryListener = new DiscoveryListener();
            registrationListener = new RegistrationListener();

            resolveListener.ServiceName = SERVICE_NAME;
            resolveListener.ServiceInfo = nsdServiceInfo;
            discoveryListener.resolveListener = resolveListener;
            discoveryListener.nsdManager = nsdManager;
        }

        public void RegisterService(string sessionName)
        {
            SERVICE_NAME = sessionName;
            // Create the NsdServiceInfo object, and populate it.
            nsdServiceInfo = new NsdServiceInfo
            {
                ServiceName = sessionName,
                ServiceType = SERVICE_TYPE,
                Port = GenerateFreePort()
            };

            InitializeNsd();
            // The name is subject to change based on conflicts
            // with other services advertised on the same network.

            nsdManager = (NsdManager) Application.Context.GetSystemService(Context.NsdService);

            nsdManager.RegisterService(
                nsdServiceInfo, NsdProtocol.DnsSd, registrationListener);
        }

        private int GenerateFreePort()
        {
            //setting the ServerSocket to 0 will generate the next free port
            var serverSocket = new ServerSocket(0);
            return serverSocket.LocalPort;
        }

        public void DiscoverServices()
        {
            nsdManager.DiscoverServices(
                SERVICE_TYPE, NsdProtocol.DnsSd, discoveryListener);
        }

        public void StopDiscovery()
        {
            nsdManager.StopServiceDiscovery(discoveryListener);
        }

        public NsdServiceInfo GetChosenServiceInfo()
        {
            return nsdServiceInfo;
        }

        public void TearDown()
        {
            nsdManager.UnregisterService(registrationListener);
        }
    }

现在,当我致电RegisterService时,我收到以下错误消息: RegisterService Error

我不知道到底哪里出错了!我在调试Xamarin应用程序时遇到的错误也没有多大帮助:(

1 个答案:

答案 0 :(得分:1)

Java.Lang.Object

继承您的RegistrationListener子类

删除Handle中的Java.Lang.Object属性和Dispose方法。

public class RegistrationListener : Java.Lang.Object,  NsdManager.IRegistrationListener
{
   ~~~
}

一旦你这样做,将生成一个ACW(Android Callable Wrapper)来绑定你的C#实现,以便它可以从Java VM实例化。