Rui Silva
Rui Silva

Reputation: 433

How to get data from Xamarin.Droid to ViewModel in Xamarin.Forms

I'm making an app for some research. I'm trying to listen to all of the wifi networks, and save them in a database. But I need to save more information then just the wifi details. I'm using Xamarin Forms for a cross platform solution. What I already have that's working: - A View that is binding with the ViewModel. - The ViewModel is working as predicted, withe the values of the entries that I've created in the View. - The project MySolution.Droid has code that accesses the wifi networks. - I have a Receiver that is firing OnReceive with the information.

What I've done that might not be the best choice: - Since after starting scan I'm waiting (async) for the OnReceive to fire. I've chosen to send the data to the ViewModel via MessagingCenter. - I'm sending with success the information. And receiving it in the ViewModel with MessagingCenter.Subscribe

What's wrong: - I can't get the information out (into my ViewModel), every property that the ViewModel has is null. - What I'd like is to just get the information to the ViewModel. Or if I could just get the information that is binding to the View in the BeginInvokeOnMainThread, that wold work just fine.

The code that I have:

ScanViewModel.cs:

    string locationName;
    public string LocationName
    {
        get
        {
            return locationName;
        }
        set
        {
            if (locationName != value)
            {
                locationName = value;
                OnPropertyChanged();
                StartScanCommand.ChangeCanExecute();
            }
        }
    }
    public ScanViewModel()
        {
        MessagingCenter.Subscribe<IScanReceiver, List<ScanResult>>(this, "receiveWiFiNetworks", (sender, arg) =>
            {
                Device.BeginInvokeOnMainThread(
                async () =>
                {
                    var l = LocationName // THIS IS NULL
                    ......
                }
                );
            });
    }

App.Droid.Wifi.cs:

    public void GetWifiNetworks()
    {
        WiFiNetworks = new List<ScanResult>();

        wifi = (WifiManager)context.GetSystemService(Context.WifiService);

        wifiReceiver = new WifiReceiver();
        context.RegisterReceiver(wifiReceiver, new IntentFilter(WifiManager.ScanResultsAvailableAction));
        wifi.StartScan();
    }

    class WifiReceiver : BroadcastReceiver, IScanReceiver
    {
        public override void OnReceive(Context context, Intent intent)
        {
            List<ScanResult> scanwifinetworks = wifi.ScanResults.ToList();

            MessagingCenter.Send<IScanReceiver, List<ScanResult>>(this, "receiveWiFiNetworks", scanwifinetworks);
        }
    }

For those who didn't read the post above (like, tldr), I'm receiving the list of ScanResult in the OnReceive and I need it to be in the ViewModel, But I also need the rest of the properties...

If there's a simpler way of doing this, I'm all ears!!!

Thanks in advance

Upvotes: 0

Views: 380

Answers (1)

Rui Silva
Rui Silva

Reputation: 433

Solution I found for my problem.

It might not be the best or cleanest way to do it, but it works for now.

In the Wifi.cs class I fill a List

    public List<ScanResult> GetWifiNetworks(){
        return WiFiNetworks;
    }

    class WifiReceiver : BroadcastReceiver, IScanReceiver
    {
        public override void OnReceive(Context context, Intent intent)
        {
            WiFiNetworks = wifi.ScanResults.ToList();
        }
    }

And I periodically get the list with a Get Method from the ViewModel as follows,

    void StartScan()
    {
        Timer _wifiAsyncTimer = new Timer();
        _wifiAsyncTimer.Elapsed += GetWifiNetworks;
        _wifiAsyncTimer.Interval = ListenPeriodicity * 1000;
        _wifiAsyncTimer.Enabled = true;
    }

    private void GetWifiNetworks(object source, ElapsedEventArgs e)
    {
        var wifiNetworks = _wifiManager.GetWifiNetworks();
        if (wifiNetworks.Count > 0)
        {
            LocationInformation LocationInformation = new LocationInformation()
            {
                LocationName = LocationName,
                Temperature = Temperature,
                Notes = Notes,
                Timestamp = DateTime.Now
            };
            LocationInformations = LocationInformation.AddWifiInformation(wifiNetworks);
        }
    }

With this, I can access all the Information and the properties aren't null.

If anybody has a better solution, I'm still all ears!!!!!

Upvotes: 1

Related Questions