Creating and implementing the LocationService class

In this section, we will take a look at how to create the LocationService class that will inherit from our ILocationService interface, and implement the underlying instance methods that we declared within our interface class. We did this to help us retrieve and continually listen for changes within the GPS location coordinates which will be used by our ViewModels and ContentPages (Views).

Let's start by creating the LocationService class for our TrackMyWalks app by performing the following steps:

  1. Ensure that the TrackMyWalks solution is open within the Visual Studio for Mac IDE.
  2. Next, right-click on the Services folder and choose Add|New File... from the pop-up menu.
  3. Then, choose the Empty Class option under the General section and enter LocationService for the name of the class to be created, as shown in the following screenshot:
Creating the LocationService Class
  1. Next, click on the New button to allow the wizard to proceed and create the new file, as shown in the preceding screenshot. Now that we have created our LocationService class, we can proceed with implementing the required code for our class.
  2. Locate and open the LocationService.cs file, which is located as part of the TrackMyWalks group, and ensure that it is displayed within the code editor. Then, enter the following code snippet:
     //
// LocationService.cs
// Location Service Class that will be used retrieve GPS Coordinates
//
// Created by Steven F. Daniel on 28/06/2018.
// Copyright © 2018 GENIESOFT STUDIOS. All rights reserved.
//
using System;
using System.Threading.Tasks;
using TrackMyWalks.Services;
using Xamarin.Forms;
using Plugin.Geolocator;
using Plugin.Geolocator.Abstractions;
using System.Diagnostics;

[assembly: Dependency(typeof(LocationService))]
namespace TrackMyWalks.Services
{
public class LocationService : ILocationService
{
// Declare our EventHandler that can be referenced within the App
public event EventHandler<PositionEventArgs> PositionChanged;

// Retrieves the current GPS Coordinates for the device
public async Task<Position> GetCurrentPosition()
{
Position position = null;
try
{
// Initialise our current location and set the accuracy in Meters
var locator = CrossGeolocator.Current;
locator.DesiredAccuracy = 200;

// Check and get a cached position if we have one
position = await locator.GetLastKnownLocationAsync();
if (position != null) return position;

// Check to see if Location Services are available / enabled
if (!locator.IsGeolocationAvailable ||
!locator.IsGeolocationEnabled)
{
return null;
}
// Call the GetPositionAsync to retrieve the GPS Coordinates
position = await locator.GetPositionAsync(TimeSpan.FromSeconds(1),
null, true);
}
catch (Exception ex)
{
Debug.WriteLine("There was a problem getting the location: " + ex);
}
// Return the current location coordinates
return position;
}

// Asynchronously listens for changes in GPS location updates
public async Task StartListening()
{
// Check to see if we are currently listening for updates
if (CrossGeolocator.Current.IsListening)
return;

// Check what Target OS Platform we are running on whenever
// the app starts
if (Device.RuntimePlatform.Equals(Device.Android))
{
await CrossGeolocator.Current.StartListeningAsync(
TimeSpan.FromSeconds(5), 10, true);
}
else
{
// Start listening for changes in location within the
// Background for iOS
await CrossGeolocator.Current.StartListeningAsync(
TimeSpan.FromSeconds(1), 100, true, new ListenerSettings
{
ActivityType = ActivityType.AutomotiveNavigation,
AllowBackgroundUpdates = true,
DeferLocationUpdates = true,
DeferralDistanceMeters = 500,
DeferralTime = TimeSpan.FromSeconds(1),
ListenForSignificantChanges = false,
PauseLocationUpdatesAutomatically = false
});
}
// EventHandler to determine whenever the GPS
// position changes
CrossGeolocator.Current.PositionChanged += (sender, e) =>
{
// Raise our PositionChanged EventHandler,
// using the Coordinates
PositionChanged.Invoke(sender, e);
};
}
// Stops listening for location service updates on the device
public async void StopListening()
{
// Checks to see if we are currently listening for updates
if (!CrossGeolocator.Current.IsListening)
return;

// Stops listening for updates, and removes our
// PositionChanged EventListener
await CrossGeolocator.Current.StopListeningAsync();
CrossGeolocator.Current.PositionChanged -= PositionChanged;
}
}
}

Now, let's start by taking a look at what we covered in the preceding code snippet:

  1. First, we started by including references to the System.Threading.Tasks, Plugin.Geolocator, and the Plugin.Geolocator.Abstractions namespaces so that we can access the classes that are defined within these namespaces. We need to include the Plugin.Geolocator and Plugin.Geolocator.Abstractions namespaces so that we can listen to changes within our GPS coordinates, as well as retrieve the current location's position.
  2. Next, we started by initializing our LocationService class to be marked as a dependency by adding the Dependency metadata attribute so that it can be resolved by the Xamarin.Forms DependencyService class. This will enable our class to find and use the method implementations defined by our ILocationService interface.
  3. Then, we needed to ensure that our LocationService class inherited from the ILocationService interface, so that it can access the instance methods, as well as any getters and setters.
  4. Then, we created an EventHandler property called PropertyChanged, that will store the GPS location coordinates whenever the location changes so that we can reference it within our ViewModels.
  5. Next, we created our GetCurrentPosition instance method, which will be responsible for retrieving the current device's GPS location. We initialized our current location object and set the accuracy to check within meters, prior to checking for and getting the cached position, if we have one.
  1. Then, we checked to see if we had location services enabled by calling both the IsGeolocationAvailable and IsGeolocationEnabled methods of the CrossGeolocator class. We return null if they have been disabled. Alternatively, we could call GeoPositionAsync to retrieve and return the current GPS geo coordinates.
  2. Next, we created our StartListening instance method, which will be responsible for asynchronously listening for changes in GPS location updates. We check to see if we were currently listening for updates by calling the IsListening property of the CrossGeolocator class, and returned our instance method if we were.
  3. Then, we proceeded to check what target OS platform we are running on and start listening for changes in the location for Android, and listened for changes within the background for iOS.
  4. Next, we created and subscribed to our EventHandler to determine whenever the GPS position changes using the PositionChanged property of the CrossGeolocator class, and then used the Invoke method on the main UI Thread and passed the GPS coordinates.
  5. Finally, we created our StopListening instance method, which will be responsible for stopping listening for location service and background updates on the device. We checked to see if we were currently listening for updates, prior to calling the StopListeningAsync method on our CrossGeolocator class, and then unsubscribed from our EventListener.

For more information on the DependencyService class, refer to the Microsoft Developer Documentation at https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/dependency-service/introduction.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.129.148.210