title: How to make background service to track GPS location even if application is closed in xamarin.forms (android)?
body: <p><strong>I am working in xamarin.forms.</strong> I want to create background service for Android. 
  <strong>My requirement is to track device location (Latitude, longitude, place name, Employee code) and inserted to the web server every after 5 min. After successful login, service has been started and for a particular employee, data is start inserting. Even if the app is closed still service should be running in background and data is keep inserting.</strong> </p>
  
  <p>My code is </p>
  
  <pre><code>using Android.App;
  using Android.Content;
  using Android.Locations;
  using Android.Net;
  using Android.OS;
  using HRMS;
  using HRMS.Interface;
  using HRMS.TableAttributes;
  using Newtonsoft.Json;
  using Plugin.Geolocator;
  using Plugin.Geolocator.Abstractions;
  using System;
  using System.Collections.Generic;
  using System.Collections.ObjectModel;
  using System.Threading;
  using System.Xml.Linq;
  using Xamarin.Forms;
  using static HRMS.ServiceLayer.ServiceClasses;
  using HRMS.MenuController;
  using HRMS.Droid;
  using Android.Provider;
  
  namespace SilverHRMS.Droid.Service
  {
      [Service]
      public class GPSTrackingService : Android.App.Service
      {
          #region Private Variables
          static readonly string TAG = "X:" + typeof(GPSTrackingService).Name;
          static int TimerWait = 300000; //150000;//25000 25 Sec; // 10 min 600000 and 20 Min 1200000
          Timer _timer;
          readonly string logTag = "GPSTrackingService";
          private string deviceId = "";
          private string googleAPI = "http://maps.googleapis.com/maps/api/geocode/xml?latlng={0},{1}&amp;sensor=false";
          #endregion
  
          /// &lt;summary&gt;
          /// 
          /// &lt;/summary&gt;
          /// &lt;param name="intent"&gt;&lt;/param&gt;
          /// &lt;param name="flags"&gt;&lt;/param&gt;
          /// &lt;param name="startId"&gt;&lt;/param&gt;
          /// &lt;returns&gt;&lt;/returns&gt;
          public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
          {
              try
              {
                  // Log.Debug(TAG, "OnStartCommand called at {2}, flags={0}, startid={1}", flags, startId, DateTime.UtcNow);
                  //_timer = new Timer(o =&gt; { Log.Debug(TAG, "Hello from GPSTrackingService. {0}", DateTime.UtcNow); GetCurrentLocation(); }, null, 0, TimerWait);
                  _timer = new Timer(o =&gt; { GetCurrentLocation(); }, null, 0, TimerWait);
  
                  //_timer = new Timer(o =&gt; { GetCurrentLocation(); }, null, 0, TimerWait);
              }
              catch (Exception ex)
              {
                  var fileService = DependencyService.Get&lt;ISaveException&gt;();
                  fileService.SaveTextAsync(App.FileName, ex.StackTrace);
  
              }
              return StartCommandResult.Sticky;
          }
  
          /// &lt;summary&gt;
          /// 
          /// &lt;/summary&gt;
          /// &lt;param name="intent"&gt;&lt;/param&gt;
          /// &lt;returns&gt;&lt;/returns&gt;
          public override IBinder OnBind(Intent intent)
          {
              // This example isn't of a bound service, so we just return NULL.
              return null;
          }
  
          /// &lt;summary&gt;
          /// On Destroy App
          /// &lt;/summary&gt;
          public override void OnDestroy()
          {
              base.OnDestroy();
  
              _timer.Dispose();
              _timer = null;
              //Log.Debug(logTag, "Service has been terminated");
          }
  
          /// &lt;summary&gt;
          /// Get Current Location and Insert to DB
          /// &lt;/summary&gt;
          public async void GetCurrentLocation()
          {
  
              try
              {
                  string statusMessage = string.Empty;
                  var locator = CrossGeolocator.Current;
                  locator.DesiredAccuracy = 100;
                  //Log.Debug(TAG, " getting GPS connection...");
                  if (App.MyEmployeeId != null)
                  {
                      #region Check Internet Connection
                      ConnectivityManager connectivityManager = (ConnectivityManager)GetSystemService(ConnectivityService);
                      NetworkInfo activeConnection = connectivityManager.ActiveNetworkInfo;
                      bool isOnline = (activeConnection != null) &amp;&amp; activeConnection.IsConnected;
                      #endregion
  
                      #region Check GPS Location Position and Emp Code
                      //LocationManager locationManager = (LocationManager)GetSystemService(LocationService);
                      bool isGPSOn = App.CheckGPSConnection();
  
                      Position position = null;
                      if (isGPSOn)
                      {
                          try
                          {
                              position = await locator.GetPositionAsync(timeoutMilliseconds: 10000);
                          }
                          catch (Exception)
                          {
                              position = null;
                          }
                      }
  
                      #endregion
  
                      #region Insert Location to Local DB or Server DB
  
                      //Device Has Internet Connection 
                      if (isOnline)
                      {
                          #region Online Location Insert Direct to the Server Database
                          if (position != null)
                          {
                              List&lt;GPSTrackingLocationClass&gt; lcListOnline = new List&lt;GPSTrackingLocationClass&gt;();
                              GPSTrackingLocationClass objGPSTrack = new GPSTrackingLocationClass();
                              objGPSTrack.Latitude = position.Latitude;
                              objGPSTrack.Longitude = position.Longitude;
                              objGPSTrack.EmpCd = App.MyEmployeeId;
                              objGPSTrack.GPS_Track_DateTime = App.GetDateTime(DateTime.Now);
  
                              IDevice device = DependencyService.Get&lt;IDevice&gt;();
                              deviceId = device.GetIdentifier();
                              deviceId = deviceId.Replace("+", "%2B");
                              objGPSTrack.DeviceId = deviceId;
  
                              string url = string.Format(googleAPI, position.Latitude, position.Longitude);
                              try
                              {
                                  XElement xml = XElement.Load(url);
                                  if (xml.Element("status").Value == "OK")
                                  {
                                      objGPSTrack.PlaceName = xml.Element("result").Element("formatted_address").Value;
                                  }
                                  else
                                  {
                                      objGPSTrack.PlaceName = string.Empty;
                                  }
                              }
                              catch (Exception ex)
                              {
  
                              }
  
                              lcListOnline.Add(objGPSTrack);
  
                              if (lcListOnline.Count &gt; 0)
                              {
                                  string jsonContentsOnline = JsonConvert.SerializeObject(lcListOnline);
                                  var responseOnline = await HRMS.ServiceLayer.GetResponseFromWebService.GetResponsePostData&lt;HRMS.ServiceLayer.ServiceClasses.RootObject&gt;(HRMS.ServiceLayer.ServiceURL.PostGPSLocation, jsonContentsOnline);
                                  if (responseOnline.Flag == true)
                                  {
                                      statusMessage = responseOnline.Message;
                                  }
                              }
                          }
                          #endregion
  
                          #region Local Database Entries Insert to Server Database
                          List&lt;LocationTracking&gt; lcListOffline = SideMenu.repoLocation.GetAllLocationAsync();
                          if (lcListOffline != null)
                          {
                              if (lcListOffline.Count &gt; 0)
                              {
                                  ObservableCollection&lt;LocationTracking&gt; lvCollection = new ObservableCollection&lt;LocationTracking&gt;(lcListOffline);
  
                                  List&lt;GPSTrackingLocationClass&gt; lcListGoingtoOnline = new List&lt;GPSTrackingLocationClass&gt;();
                                  foreach (var item in lvCollection)
                                  {
                                      GPSTrackingLocationClass objGPSTrackOffline = new GPSTrackingLocationClass();
                                      objGPSTrackOffline.Latitude = item.Latitude;
                                      objGPSTrackOffline.Longitude = item.Longitude;
                                      objGPSTrackOffline.EmpCd = item.EmpCd;
                                      objGPSTrackOffline.GPS_Track_DateTime = item.GPS_Track_DateTime;
                                      objGPSTrackOffline.DeviceId = item.DeviceID;
  
                                      string urlAPI = string.Format(googleAPI, item.Latitude, item.Longitude);
  
                                      try
                                      {
                                          XElement xmlURL = XElement.Load(urlAPI);
                                          if (xmlURL.Element("status").Value == "OK")
                                          {
                                              objGPSTrackOffline.PlaceName = xmlURL.Element("result").Element("formatted_address").Value;
                                          }
                                          else
                                          {
                                              objGPSTrackOffline.PlaceName = string.Empty;
                                          }
                                      }
                                      catch (Exception exe)
                                      {
  
                                      }
  
                                      if (!string.IsNullOrEmpty(objGPSTrackOffline.PlaceName))
                                      {
                                          lcListGoingtoOnline.Add(objGPSTrackOffline);
                                      }
                                  }
  
                                  if (lcListGoingtoOnline.Count == lvCollection.Count)
                                  {
                                      string jsonContentsOffline = JsonConvert.SerializeObject(lcListGoingtoOnline);
                                      var responseOffline = await HRMS.ServiceLayer.GetResponseFromWebService.GetResponsePostData&lt;HRMS.ServiceLayer.ServiceClasses.RootObject&gt;(HRMS.ServiceLayer.ServiceURL.PostGPSLocation, jsonContentsOffline);
                                      if (responseOffline.Flag == true)
                                      {
                                          statusMessage = responseOffline.Message;
                                          SideMenu.repoLocation.RemoveLocationAsync();
                                      }
                                  }
                              }
                          }
                          #endregion
                      }
                      //Device Has No Internet Connection 
                      else
                      {
                          try
                          {
                              if (position != null)
                              {
                                  IDevice device = DependencyService.Get&lt;IDevice&gt;();
                                  deviceId = device.GetIdentifier();
                                  deviceId = deviceId.Replace("+", "%2B");
                                  string newDate = App.GetDateTime(DateTime.Now);
                                  SideMenu.repoLocation.AddNewLocationAsync(newDate, position.Latitude, position.Longitude, App.MyEmployeeId, deviceId, "--");
                              }
                          }
                          catch (Exception ex)
                          {
                              //Log.Debug(TAG, "Please turn on GPS in your headset");
                          }
                      }
                      #endregion
                  }
              } 
              catch (Exception ex) 
              {
                  var fileService = DependencyService.Get&lt;ISaveException&gt;();
                  await fileService.SaveTextAsync(App.FileName, ex.StackTrace);
              }
          }
  
          /// &lt;summary&gt;
          /// Start Location Service
          /// &lt;/summary&gt;
          public static void StartLocationService()
          {
              // Starting a service like this is blocking, so we want to do it on a background thread
              //new Task(() =&gt;
              //{
              // Start our main service
              try
              {
                  Intent intent = new Intent(Android.App.Application.Context, typeof(GPSTrackingService));
                  Android.App.Application.Context.StartService(intent);
              }
              catch (Exception ex)
              {
                  var fileService = DependencyService.Get&lt;ISaveException&gt;();
                  fileService.SaveTextAsync(App.FileName, ex.StackTrace);
              }
              //}).Start();
          }
  
          /// &lt;summary&gt;
          /// Start Location Service
          /// &lt;/summary&gt;
          public static void StartApplication()
          {
              try
              {
                  Intent start = new Intent(Android.App.Application.Context, typeof(MainActivity));
                  // my activity name is MainActivity replace it with yours
                  start.AddFlags(ActivityFlags.NewTask);
                  Android.App.Application.Context.ApplicationContext.StartActivity(start);
              }
              catch (Exception ex)
              {
                  var fileService = DependencyService.Get&lt;ISaveException&gt;();
                  fileService.SaveTextAsync(App.FileName, ex.StackTrace);
              }
          }
  
          public static void SendEmail(string text)
          {
              var email = new Intent(Android.Content.Intent.ActionSend);
              email.PutExtra(Android.Content.Intent.ExtraEmail, new string[] { "pankit.patel@silvertouch.com" });
              email.PutExtra(Android.Content.Intent.ExtraSubject, "Send Crash Report");
              email.PutExtra(Android.Content.Intent.ExtraText, "Hello, " + text);
              email.AddFlags(ActivityFlags.NewTask);
              email.SetType("message/rfc822");
              Android.App.Application.Context.ApplicationContext.StartActivity(email);
          }
  
          /// &lt;summary&gt;
          /// Stop Location Service
          /// &lt;/summary&gt;
          public static void StopLocationService()
          {
  
              // Check for nulls in case StartLocationService task has not yet completed.
              //Log.Debug("App", "StopGPSTrackingService");
              try
              {
                  Intent intent = new Intent(Android.App.Application.Context, typeof(GPSTrackingService));
                  Android.App.Application.Context.StopService(intent);
              }
              catch (Exception ex)
              {
                  var fileService = DependencyService.Get&lt;ISaveException&gt;();
                  fileService.SaveTextAsync(App.FileName, ex.StackTrace);
              }
          }
  
      }
  }
  </code></pre>
  
  <p><strong>This service is only running when app is open (even in background) but if I close the app then service is automatically stop working. How to solve this issue? I have so many xamarin blogs regarding this topic but I din't get any workaround yet</strong>. </p>
  
  <p><strong>How to make background service that should be running even after app is close?</strong></p>