【问题标题】:Is there a way to create a timeout to an attempt to connection with Xamarin.Forms?有没有办法创建超时以尝试与 Xamarin.Forms 连接?
【发布时间】:2020-11-10 14:40:27
【问题描述】:

如果我尝试连接到特定的 SSID 并且已经过了一些等待时间,我正在尝试发出警告。我已尝试使用 Timer 类,但存在一些我无法解决的任务和线程问题。

这是我在 Xamarin.Droid 中的 Wifi 课程

public class Wifi : Iwifi
{
    private Context context;
    private static WifiManager _manager;
    private MyReceiver _receiver;

    public void Initialize()
    {
        context = Android.App.Application.Context;
        _manager = (WifiManager)context.GetSystemService(Context.WifiService);
        _receiver = new MyReceiver();
    }

    public void Register()
    {
        IntentFilter intents = new IntentFilter();
        intents.AddAction(WifiManager.ScanResultAction);
        intents.AddAction(WifiManager.NetworkStateChangedAction);
        context.RegisterReceiver(_receiver, intents);
    }

    public void Unregister()
    {
        context.UnregisterReceiver(_receiver);
    }

    public void ScanWirelessDevices()
    {
        _manager.StartScan();
    }

    public string GetConnectionSSID()
    {
        return _manager.ConnectionInfo.SSID;
    }

    public void ConnectToSSID(string SSID, string pwd)
    {
        if (!_manager.IsWifiEnabled)
        {
            _manager.SetWifiEnabled(true);
        }
        WifiConfiguration wifiConfiguration = new WifiConfiguration();
        wifiConfiguration.Ssid = '"' + SSID + '"';
        if (pwd.Empty)
        {
            wifiConfiguration.AllowedKeyManagement.Set((int)KeyManagementType.None);
        }
        else
        {
            //Configuration for protected Network
        }
        var addNet = _manager.AddNetwork(wifiConfiguration);
        if (addNet == -1)
        {
            _manager.Disconnect();
            _manager.EnableNetwork(addNet, true);
            _manager.Reconnect();
            return;
        }
        var list = _manager.ConfiguredNetworks;
        foreach (WifiConfiguration conf in list)
        {
            if (conf.Ssid.Equals('"' + SSID + '"'))
            {
                _manager.Disconnect();
                _manager.EnableNetwork(conf.NetworkId, true);
                _manager.Reconnect();
                return;
            }
        }
    }

    public class MyReceiver : BroadcastReceiver
    {
        public override void OnReceive(Context context, Intent intent)
        {
            if (intent.Action.Equals(WifiManager.ScanResultAvailableAction))
            {
                IList<ScanResult> scanResult = _manager.ScanResult;
                App.Networks.NetworksList.Clear();
                foreach (ScanResult result in scanResult)
                {
                    App.Networks.NetworksList.Add(result.Ssid);
                }
            }
        }
    }
}

那么这是 Xamarin.Forms 中 App 类的一部分

public partial class App: Application
{
    private static ...
    .
    .
    .
    private static string _selectedSSID;
    private static MainDetail _pageDetail;

    public static IWifi WifiManager { get; } = DependencyService.Get<Iwifi>();
    public static string SelectedSSID { get { return _selectedSSID; } set { _selectedSSID = value; } }
    public static MainDetail PageDetail { get { return _pageDetail; } }

    public App()
    {
        InitializeComponent();
        WifiManager.Initialize();
        WifiManager.Register();
        InitViews();
        MainPage = _mainPage;
        Connectivity.ConnectivityChanged += NetworkEvents;
        NetSearch();
    }

    .
    .
    .
   
    public void NetSearch()
    {
        Task.Run(async () =>
        {
            while (true)
            {                 
                WifiManager.ScanWirelessDevices();
                await Task.Delay(Utility.SCAN_WIFI_TIMER); //waiting 31000 milliseconds because of Scanning throttling
            }
        });
    }

    public void NetworkEvents(object sender, ConnectivityChangedEventArgs e)
    {
        MainMaster master = (MainMaster)_mainPage.Master;

        if (e.NetworkAccess == NetworkAccess.Unknown)
        {
            Debug.WriteLine("Network Access Unknown " + e.ToString());
        }
        if (e.NetworkAccess == NetworkAccess.None)
        {
            Debug.WriteLine("Network Access None " + e.ToString());
        }
        if (e.NetworkAccess == NetworkAccess.Local)
        {
            Debug.WriteLine("Network Access Local " + e.ToString());
        }
        if (e.NetworkAccess == NetworkAccess.Internet)
        {
            if(selectedSSID == Wifimanager.GetConnectionInfo())
            {
                //WE CONNECTED!!
                //Now I want to stop the Timeout Timer to attempt
            }
        }
        if (e.NetworkAccess == NetworkAccess.ConstrainedInternet)
        {
            Debug.WriteLine("Network Access Constrainde Internet " + e.ToString());
        }
    }
}

以及详细信息页面类的一部分,我在其中启动连接事件以及我想要启动超时计时器的位置

public partial class MainDetail : ContentPage
{
    .
    .
    .

    public void OnItemListClicked(object sender, SelectedItemChangedEventArgs e)
    {
        if (e.SelectedItem == null)
        {
            return;
        }
        ImageCell item = (ImageCell)e.SelectedItem;
        App.SelectedSSID = item.Text;
        App.WifiManager.ConnectToSSID(item.Text, "");
        ActivityIndicator(true);
        //Now the timer should start.
        //And call PageDetail.ActivityIndicator(false) and warning the user if the timeout go to 0.
        listView.SelectedItem = null;
    }

}

我尝试使用 Timers Timer 类,但不起作用.. 有什么建议吗?

【问题讨论】:

    标签: c# xamarin xamarin.forms xamarin.android


    【解决方案1】:

    好的,我想出了一个解决方案!我没有使用 Thread 和 Task,而是使用了 Device.StartTimer。

    在我写的 DetailPage 事件中:

    public void OnItemListClicked(object sender, SelectedItemChangedEventArgs e)
    {
        if (e.SelectedItem == null)
        {
            return;
        }
        ImageCell item = (ImageCell)e.SelectedItem;
        App.SelectedSSID = item.Text;
        App.WifiManager.ConnectToSSID(item.Text, "");
        ActivityIndicator(true);
        Device.StartTimer(TimeSpan.FromSeconds(10), () =>   //Waiting 10 second then if we are not connected fire the event.
        {
            Device.BeginInvokeOnMainThread(() =>
            {
                if (App.IsLogout) //variable I use to check if I can do the logout or not
                {
                    ActivityIndicator(false);
                    App.SelectedSSID = "";
                    //My message to users "Fail to connect"
                }
            });
            return false;
        });
        listView.SelectedItem = null;
    }
    

    【讨论】:

    • 感谢您的分享,请采纳您的回答,它将帮助其他有类似问题的人。
    • 是的,我知道,但系统只能让我明天才能这样做。希望这对其他人有所帮助。
    猜你喜欢
    • 2014-11-19
    • 1970-01-01
    • 1970-01-01
    • 2015-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多