GeoTracker.cs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Threading.Tasks;
  5. using Windows.Devices.Geolocation;
  6. using Windows.Devices.Geolocation.Geofencing;
  7. using Windows.System;
  8. namespace YJMPD_UWP.Model
  9. {
  10. public class GeoTracker
  11. {
  12. private Geolocator geo;
  13. private PositionStatus _status;
  14. public PositionStatus Status { get { return _status; } }
  15. private Geoposition _position;
  16. public Geoposition Position { get { return _position; } }
  17. public bool? Connected { get; private set; }
  18. private List<Geoposition> _history;
  19. public List<Geoposition> History
  20. {
  21. get
  22. {
  23. return _history;
  24. }
  25. }
  26. //Events
  27. public delegate void PositionUpdateHandler(object sender, PositionUpdatedEventArgs e);
  28. public event PositionUpdateHandler OnPositionUpdate;
  29. public delegate void StatusUpdateHandler(object sender, StatusUpdatedEventArgs e);
  30. public event StatusUpdateHandler OnStatusUpdate;
  31. public GeoTracker()
  32. {
  33. _status = PositionStatus.NotInitialized;
  34. Connected = false;
  35. _history = new List<Geoposition>();
  36. StartTracking();
  37. }
  38. public async void ForceRefresh()
  39. {
  40. if (geo == null)
  41. await StartTracking();
  42. else
  43. _position = await geo.GetGeopositionAsync();
  44. }
  45. public async void TryConnectIfNull()
  46. {
  47. if (geo == null)
  48. await StartTracking();
  49. }
  50. public void ClearHistory()
  51. {
  52. _history.Clear();
  53. }
  54. public async Task<String> StartTracking()
  55. {
  56. // Request permission to access location
  57. if (Status != PositionStatus.NotAvailable && Status != PositionStatus.NotInitialized)
  58. return "Already Connected";
  59. var accessStatus = await Geolocator.RequestAccessAsync();
  60. switch (accessStatus)
  61. {
  62. case GeolocationAccessStatus.Allowed:
  63. geo = new Geolocator
  64. {
  65. DesiredAccuracy = PositionAccuracy.High,
  66. MovementThreshold = 3
  67. //ReportInterval = 1500
  68. };
  69. ClearHistory();
  70. Connected = true;
  71. geo.PositionChanged += Geo_PositionChanged;
  72. geo.StatusChanged += Geo_StatusChanged;
  73. GeofenceMonitor.Current.Geofences.Clear();
  74. _position = await geo.GetGeopositionAsync();
  75. return "Connected";
  76. case GeolocationAccessStatus.Denied:
  77. Connected = false;
  78. _status = PositionStatus.NotAvailable;
  79. bool result = await Launcher.LaunchUriAsync(new Uri("ms-settings:privacy-location"));
  80. return "Denied";
  81. default:
  82. case GeolocationAccessStatus.Unspecified:
  83. Connected = false;
  84. _status = PositionStatus.NotAvailable;
  85. return "Error";
  86. }
  87. }
  88. private void Geo_StatusChanged(Geolocator sender, StatusChangedEventArgs args)
  89. {
  90. if (args.Status == PositionStatus.Disabled)
  91. {
  92. Connected = false;
  93. _position = null;
  94. }
  95. else if (!(bool)Connected)
  96. Connected = true;
  97. UpdateStatus(args.Status);
  98. }
  99. private void Geo_PositionChanged(Geolocator sender, PositionChangedEventArgs args)
  100. {
  101. if (_history.Count > 0)
  102. UpdatePosition(_history.Last(), args.Position);
  103. else
  104. {
  105. _position = args.Position;
  106. UpdatePosition(args.Position, args.Position);
  107. }
  108. _history.Add(args.Position);
  109. }
  110. private void UpdateStatus(PositionStatus s)
  111. {
  112. _status = s;
  113. if (OnStatusUpdate == null) return;
  114. OnStatusUpdate(this, new StatusUpdatedEventArgs(s));
  115. }
  116. private void UpdatePosition(Geoposition old, Geoposition newp)
  117. {
  118. _position = newp;
  119. if (OnPositionUpdate == null) return;
  120. OnPositionUpdate(this, new PositionUpdatedEventArgs(old, newp));
  121. }
  122. }
  123. public class PositionUpdatedEventArgs : EventArgs
  124. {
  125. public Geoposition Old { get; private set; }
  126. public Geoposition New { get; private set; }
  127. public PositionUpdatedEventArgs(Geoposition old, Geoposition notold)
  128. {
  129. Old = old;
  130. New = notold;
  131. }
  132. }
  133. public class StatusUpdatedEventArgs : EventArgs
  134. {
  135. public PositionStatus Status { get; private set; }
  136. public StatusUpdatedEventArgs(PositionStatus status)
  137. {
  138. Status = status;
  139. }
  140. }
  141. }