有没有一种方法可以创建超时以尝试与Xamarin.Forms建立连接?

时间:2020-11-10 14:40:27

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

如果我尝试连接到特定的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类,但是没有任何建议。

1 个答案:

答案 0 :(得分:0)

好吧,我找到了解决方案!我没有使用线程和任务,而是使用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;
}