【问题标题】:How to properly implement Xamarin NetworkServiceDiscovery via DependencyService?如何通过 DependencyService 正确实现 Xamarin NetworkServiceDiscovery?
【发布时间】:2017-09-30 15:13:29
【问题描述】:

我有一个 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。

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

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 时,我收到以下错误:

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

【问题讨论】:

    标签: c# xamarin xamarin.android


    【解决方案1】:

    Java.Lang.Object 继承您的 RegistrationListener 子类

    删除Handle 属性和Dispose 方法,因为它们在Java.Lang.Object 中实现。

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

    执行此操作后,将生成一个 ACW(Android 可调用包装器)来绑定您的 C# 实现,以便可以从 Java VM 实例化它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-06-28
      • 2014-07-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-27
      • 2013-07-22
      相关资源
      最近更新 更多