public static void ExecuteNetworkCommand(ExecuteNetworkDelegate command, object connManager)
        {
#if Android
            if (Android.OS.Build.VERSION.SdkInt < Android.OS.BuildVersionCodes.Lollipop)
            {
                command();
                return;
            }
            Android.Net.Network             bindNetwork         = null;
            Android.Net.ConnectivityManager connectivityManager = connManager as Android.Net.ConnectivityManager;
            // ReSharper disable once UseNullPropagation
            if (connectivityManager != null)
            {
                Android.Net.Network[] networks = connectivityManager.GetAllNetworks();
                if (networks != null)
                {
                    foreach (Android.Net.Network network in networks)
                    {
                        Android.Net.NetworkInfo         networkInfo         = connectivityManager.GetNetworkInfo(network);
                        Android.Net.NetworkCapabilities networkCapabilities = connectivityManager.GetNetworkCapabilities(network);
                        // HasTransport support started also with Lollipop
                        if (networkInfo != null && networkInfo.IsConnected &&
                            networkCapabilities != null && networkCapabilities.HasTransport(Android.Net.TransportType.Wifi))
                        {
                            bindNetwork = network;
                            break;
                        }
                    }
                }
            }
            if (Android.OS.Build.VERSION.SdkInt < Android.OS.BuildVersionCodes.M)
            {
#pragma warning disable 618
                Android.Net.Network defaultNetwork = Android.Net.ConnectivityManager.ProcessDefaultNetwork;
                try
                {
                    Android.Net.ConnectivityManager.SetProcessDefaultNetwork(bindNetwork);
                    command();
                }
                finally
                {
                    Android.Net.ConnectivityManager.SetProcessDefaultNetwork(defaultNetwork);
                }
#pragma warning restore 618
                return;
            }
            Android.Net.Network boundNetwork = connectivityManager?.BoundNetworkForProcess;
            try
            {
                connectivityManager?.BindProcessToNetwork(bindNetwork);
                command();
            }
            finally
            {
                connectivityManager?.BindProcessToNetwork(boundNetwork);
            }
#else
            command();
#endif
        }
        public static void ExecuteNetworkCommand(ExecuteNetworkDelegate command, IPAddress ipAddr, object networkDataObject)
        {
#if Android
            if (Android.OS.Build.VERSION.SdkInt < Android.OS.BuildVersionCodes.Lollipop)
            {
                command();
                return;
            }
            Android.Net.Network             bindNetwork         = null;
            NetworkData                     networkData         = networkDataObject as NetworkData;
            Android.Net.ConnectivityManager connectivityManager = networkData?.ConnectivityManager;
            Java.Net.InetAddress            inetAddr            = Java.Net.InetAddress.GetByName(ipAddr.ToString());
            // ReSharper disable once UseNullPropagation
            if (connectivityManager != null && inetAddr is Java.Net.Inet4Address inet4Addr)
            {
                System.Collections.Generic.List <Android.Net.Network> networkList = new System.Collections.Generic.List <Android.Net.Network>();
                lock (networkData.LockObject)
                {
                    networkList.AddRange(networkData.ActiveWifiNetworks);
                    networkList.AddRange(networkData.ActiveEthernetNetworks);
                }

                foreach (Android.Net.Network network in networkList)
                {
                    Android.Net.NetworkCapabilities networkCapabilities = connectivityManager.GetNetworkCapabilities(network);
                    // HasTransport support started also with Lollipop
                    if (networkCapabilities != null)
                    {
                        bool linkValid = false;
                        Android.Net.LinkProperties linkProperties = connectivityManager.GetLinkProperties(network);
                        if (linkProperties != null)
                        {
                            foreach (Android.Net.LinkAddress linkAddress in linkProperties.LinkAddresses)
                            {
                                if (linkAddress.Address is Java.Net.Inet4Address linkInet4Address)
                                {
                                    Java.Net.NetworkInterface networkInterface = Java.Net.NetworkInterface.GetByInetAddress(linkInet4Address);
                                    if (networkInterface != null && networkInterface.IsUp &&
                                        (linkInet4Address.IsSiteLocalAddress || linkInet4Address.IsLinkLocalAddress))
                                    {
                                        foreach (Java.Net.InterfaceAddress interfaceAddress in networkInterface.InterfaceAddresses)
                                        {
                                            if (interfaceAddress.Address is Java.Net.Inet4Address)
                                            {
                                                byte[] linkAddrBytes  = interfaceAddress.Address.GetAddress();
                                                byte[] inet4AddrBytes = inet4Addr.GetAddress();
                                                if (linkAddrBytes.Length == inet4AddrBytes.Length)
                                                {
                                                    for (int bit = interfaceAddress.NetworkPrefixLength; bit < linkAddrBytes.Length * 8; bit++)
                                                    {
                                                        int  index = bit >> 3;
                                                        byte mask  = (byte)(0x80 >> (bit & 0x07));
                                                        linkAddrBytes[index]  |= mask;
                                                        inet4AddrBytes[index] |= mask;
                                                    }
                                                }

                                                if (linkAddrBytes.SequenceEqual(inet4AddrBytes))
                                                {
                                                    linkValid = true;
                                                    break;
                                                }
                                            }
                                        }

                                        if (linkValid)
                                        {
                                            break;
                                        }
                                    }
                                }
                            }
                        }

                        if (linkValid)
                        {
                            bindNetwork = network;
                            break;
                        }
                    }
                }
            }

            if (Android.OS.Build.VERSION.SdkInt < Android.OS.BuildVersionCodes.M)
            {
#pragma warning disable 618
                Android.Net.Network defaultNetwork = Android.Net.ConnectivityManager.ProcessDefaultNetwork;
                try
                {
                    Android.Net.ConnectivityManager.SetProcessDefaultNetwork(bindNetwork);
                    command();
                }
                finally
                {
                    Android.Net.ConnectivityManager.SetProcessDefaultNetwork(defaultNetwork);
                }
#pragma warning restore 618
                return;
            }
            Android.Net.Network boundNetwork = connectivityManager?.BoundNetworkForProcess;
            try
            {
                connectivityManager?.BindProcessToNetwork(bindNetwork);
                command();
            }
            finally
            {
                connectivityManager?.BindProcessToNetwork(boundNetwork);
            }
#else
            command();
#endif
        }
        public static void ExecuteNetworkCommand(ExecuteNetworkDelegate command, object connManager, bool checkEthernet = false)
        {
#if Android
            if (Android.OS.Build.VERSION.SdkInt < Android.OS.BuildVersionCodes.Lollipop)
            {
                command();
                return;
            }
            Android.Net.Network             bindNetwork         = null;
            Android.Net.ConnectivityManager connectivityManager = connManager as Android.Net.ConnectivityManager;
            // ReSharper disable once UseNullPropagation
            if (connectivityManager != null)
            {
                Android.Net.Network[] networks = connectivityManager.GetAllNetworks();
                if (networks != null)
                {
                    foreach (Android.Net.Network network in networks)
                    {
                        Android.Net.NetworkInfo         networkInfo         = connectivityManager.GetNetworkInfo(network);
                        Android.Net.NetworkCapabilities networkCapabilities = connectivityManager.GetNetworkCapabilities(network);
                        // HasTransport support started also with Lollipop
                        if (networkInfo != null && networkInfo.IsConnected && networkCapabilities != null)
                        {
                            bool linkValid = false;
                            bool autoIp    = false;
                            Android.Net.LinkProperties linkProperties = connectivityManager.GetLinkProperties(network);
                            foreach (Android.Net.LinkAddress linkAddress in linkProperties.LinkAddresses)
                            {
                                if (linkAddress.Address is Java.Net.Inet4Address inet4Address)
                                {
                                    if (inet4Address.IsSiteLocalAddress || inet4Address.IsLinkLocalAddress)
                                    {
                                        linkValid = true;
                                        autoIp    = inet4Address.IsLinkLocalAddress;
                                        break;
                                    }
                                }
                            }

                            if (linkValid)
                            {
                                if (networkCapabilities.HasTransport(Android.Net.TransportType.Wifi))
                                {
                                    bindNetwork = network;
                                }
                                if (checkEthernet && networkCapabilities.HasTransport(Android.Net.TransportType.Ethernet))
                                {
                                    if (autoIp)
                                    {
                                        // prefer Ethernet auto ip
                                        bindNetwork = network;
                                        break;
                                    }

                                    if (bindNetwork == null)
                                    {
                                        // prefer Wifi
                                        bindNetwork = network;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            if (Android.OS.Build.VERSION.SdkInt < Android.OS.BuildVersionCodes.M)
            {
#pragma warning disable 618
                Android.Net.Network defaultNetwork = Android.Net.ConnectivityManager.ProcessDefaultNetwork;
                try
                {
                    Android.Net.ConnectivityManager.SetProcessDefaultNetwork(bindNetwork);
                    command();
                }
                finally
                {
                    Android.Net.ConnectivityManager.SetProcessDefaultNetwork(defaultNetwork);
                }
#pragma warning restore 618
                return;
            }
            Android.Net.Network boundNetwork = connectivityManager?.BoundNetworkForProcess;
            try
            {
                connectivityManager?.BindProcessToNetwork(bindNetwork);
                command();
            }
            finally
            {
                connectivityManager?.BindProcessToNetwork(boundNetwork);
            }
#else
            command();
#endif
        }