即使应用程序在xamarin.forms(android)中关闭,如何使后台服务跟踪GPS位置?

时间:2017-07-29 18:10:21

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

我在xamarin.forms工作。我想为Android创建后台服务。 我的要求是跟踪设备位置(纬度,经度,地名,员工代码),并在每5分钟后插入网络服务器。成功登录后,服务已启动,对于特定员工,数据将开始插入。即使应用程序已关闭,仍然应该在后台运行服务,并且数据会继续插入。

我的代码是

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}&sensor=false";
        #endregion

        /// <summary>
        /// 
        /// </summary>
        /// <param name="intent"></param>
        /// <param name="flags"></param>
        /// <param name="startId"></param>
        /// <returns></returns>
        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 => { Log.Debug(TAG, "Hello from GPSTrackingService. {0}", DateTime.UtcNow); GetCurrentLocation(); }, null, 0, TimerWait);
                _timer = new Timer(o => { GetCurrentLocation(); }, null, 0, TimerWait);

                //_timer = new Timer(o => { GetCurrentLocation(); }, null, 0, TimerWait);
            }
            catch (Exception ex)
            {
                var fileService = DependencyService.Get<ISaveException>();
                fileService.SaveTextAsync(App.FileName, ex.StackTrace);

            }
            return StartCommandResult.Sticky;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="intent"></param>
        /// <returns></returns>
        public override IBinder OnBind(Intent intent)
        {
            // This example isn't of a bound service, so we just return NULL.
            return null;
        }

        /// <summary>
        /// On Destroy App
        /// </summary>
        public override void OnDestroy()
        {
            base.OnDestroy();

            _timer.Dispose();
            _timer = null;
            //Log.Debug(logTag, "Service has been terminated");
        }

        /// <summary>
        /// Get Current Location and Insert to DB
        /// </summary>
        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) && 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<GPSTrackingLocationClass> lcListOnline = new List<GPSTrackingLocationClass>();
                            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<IDevice>();
                            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 > 0)
                            {
                                string jsonContentsOnline = JsonConvert.SerializeObject(lcListOnline);
                                var responseOnline = await HRMS.ServiceLayer.GetResponseFromWebService.GetResponsePostData<HRMS.ServiceLayer.ServiceClasses.RootObject>(HRMS.ServiceLayer.ServiceURL.PostGPSLocation, jsonContentsOnline);
                                if (responseOnline.Flag == true)
                                {
                                    statusMessage = responseOnline.Message;
                                }
                            }
                        }
                        #endregion

                        #region Local Database Entries Insert to Server Database
                        List<LocationTracking> lcListOffline = SideMenu.repoLocation.GetAllLocationAsync();
                        if (lcListOffline != null)
                        {
                            if (lcListOffline.Count > 0)
                            {
                                ObservableCollection<LocationTracking> lvCollection = new ObservableCollection<LocationTracking>(lcListOffline);

                                List<GPSTrackingLocationClass> lcListGoingtoOnline = new List<GPSTrackingLocationClass>();
                                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<HRMS.ServiceLayer.ServiceClasses.RootObject>(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<IDevice>();
                                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<ISaveException>();
                await fileService.SaveTextAsync(App.FileName, ex.StackTrace);
            }
        }

        /// <summary>
        /// Start Location Service
        /// </summary>
        public static void StartLocationService()
        {
            // Starting a service like this is blocking, so we want to do it on a background thread
            //new Task(() =>
            //{
            // 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<ISaveException>();
                fileService.SaveTextAsync(App.FileName, ex.StackTrace);
            }
            //}).Start();
        }

        /// <summary>
        /// Start Location Service
        /// </summary>
        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<ISaveException>();
                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);
        }

        /// <summary>
        /// Stop Location Service
        /// </summary>
        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<ISaveException>();
                fileService.SaveTextAsync(App.FileName, ex.StackTrace);
            }
        }

    }
}

此服务仅在应用程序打开时运行(即使在后台)但如果我关闭应用程序,则服务会自动停止工作。如何解决这个问题?我有很多关于这个主题的xamarin博客,但我还没有得到任何解决方法

即使在应用关闭后,如何制作应该运行的后台服务?

0 个答案:

没有答案