Skip to content

Commit d2bd5a5

Browse files
committed
UWP location service added.
1 parent 41398ab commit d2bd5a5

3 files changed

Lines changed: 201 additions & 0 deletions

File tree

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using System;
2+
using System.Threading;
3+
using System.Threading.Tasks;
4+
5+
namespace eShopOnContainers.Windows.Helpers
6+
{
7+
internal class Timeout
8+
{
9+
public const int Infinite = -1;
10+
readonly CancellationTokenSource _canceller = new CancellationTokenSource();
11+
12+
public Timeout(int timeout, Action timesUp)
13+
{
14+
if (timeout == Infinite)
15+
return;
16+
if (timeout < 0)
17+
throw new ArgumentOutOfRangeException("timeoutMilliseconds");
18+
if (timesUp == null)
19+
throw new ArgumentNullException("timesUp");
20+
21+
Task.Delay(TimeSpan.FromMilliseconds(timeout), _canceller.Token).ContinueWith(t =>
22+
{
23+
if (!t.IsCanceled)
24+
timesUp();
25+
});
26+
}
27+
28+
public void Cancel()
29+
{
30+
_canceller.Cancel();
31+
}
32+
}
33+
}
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
using eShopOnContainers.Core.Models.Location;
2+
using eShopOnContainers.Core.Services.Location;
3+
using System;
4+
using System.Threading;
5+
using System.Threading.Tasks;
6+
using Windows.Devices.Geolocation;
7+
using Windows.Foundation;
8+
9+
[assembly: Xamarin.Forms.Dependency(typeof(ILocationServiceImplementation))]
10+
namespace eShopOnContainers.Windows.Services
11+
{
12+
public class LocationServiceImplementation : ILocationServiceImplementation
13+
{
14+
double _desiredAccuracy;
15+
Geolocator _locator = new Geolocator();
16+
17+
public LocationServiceImplementation()
18+
{
19+
DesiredAccuracy = 100;
20+
}
21+
22+
#region Internal Implementation
23+
24+
Geolocator GetGeolocator()
25+
{
26+
var loc = _locator;
27+
if (loc == null)
28+
{
29+
_locator = new Geolocator();
30+
_locator.StatusChanged += OnLocatorStatusChanged;
31+
loc = _locator;
32+
}
33+
return loc;
34+
}
35+
36+
PositionStatus GetGeolocatorStatus()
37+
{
38+
var loc = GetGeolocator();
39+
return loc.LocationStatus;
40+
}
41+
42+
static Position GetPosition(Geoposition position)
43+
{
44+
var pos = new Position
45+
{
46+
Accuracy = position.Coordinate.Accuracy,
47+
Altitude = position.Coordinate.Point.Position.Altitude,
48+
Latitude = position.Coordinate.Point.Position.Latitude,
49+
Longitude = position.Coordinate.Point.Position.Longitude,
50+
Timestamp = position.Coordinate.Timestamp.ToUniversalTime()
51+
};
52+
53+
if (position.Coordinate.Heading != null)
54+
pos.Heading = position.Coordinate.Heading.Value;
55+
if (position.Coordinate.Speed != null)
56+
pos.Speed = position.Coordinate.Speed.Value;
57+
if (position.Coordinate.AltitudeAccuracy.HasValue)
58+
pos.AltitudeAccuracy = position.Coordinate.AltitudeAccuracy.Value;
59+
60+
return pos;
61+
}
62+
63+
async void OnLocatorStatusChanged(Geolocator sender, StatusChangedEventArgs e)
64+
{
65+
GeolocationError error;
66+
67+
switch (e.Status)
68+
{
69+
case PositionStatus.Disabled:
70+
error = GeolocationError.Unauthorized;
71+
break;
72+
case PositionStatus.NoData:
73+
error = GeolocationError.PositionUnavailable;
74+
break;
75+
default:
76+
return;
77+
}
78+
_locator = null;
79+
}
80+
81+
#endregion
82+
83+
#region ILocationServiceImplementation
84+
85+
public double DesiredAccuracy
86+
{
87+
get { return _desiredAccuracy; }
88+
set
89+
{
90+
_desiredAccuracy = value;
91+
GetGeolocator().DesiredAccuracy = (value < 100) ? PositionAccuracy.High : PositionAccuracy.Default;
92+
}
93+
}
94+
95+
public event EventHandler<PositionErrorEventArgs> PositionError;
96+
public event EventHandler<PositionEventArgs> PositionChanged;
97+
98+
public bool IsGeolocationAvailable
99+
{
100+
get
101+
{
102+
var status = GetGeolocatorStatus();
103+
while (status == PositionStatus.Initializing)
104+
{
105+
Task.Delay(10).Wait();
106+
status = GetGeolocatorStatus();
107+
}
108+
return status != PositionStatus.NotAvailable;
109+
}
110+
}
111+
112+
public bool IsGeolocationEnabled
113+
{
114+
get
115+
{
116+
var status = GetGeolocatorStatus();
117+
while (status == PositionStatus.Initializing)
118+
{
119+
Task.Delay(10).Wait();
120+
status = GetGeolocatorStatus();
121+
}
122+
return status != PositionStatus.Disabled && status != PositionStatus.NotAvailable;
123+
}
124+
}
125+
126+
public Task<Position> GetPositionAsync(TimeSpan? timeout = null, CancellationToken? cancelToken = null, bool includeHeading = false)
127+
{
128+
var timeoutMilliseconds = timeout.HasValue ? (int)timeout.Value.TotalMilliseconds : eShopOnContainers.Windows.Helpers.Timeout.Infinite;
129+
if (timeoutMilliseconds < 0 && timeoutMilliseconds != eShopOnContainers.Windows.Helpers.Timeout.Infinite)
130+
throw new ArgumentOutOfRangeException(nameof(timeout));
131+
132+
if (!cancelToken.HasValue)
133+
cancelToken = CancellationToken.None;
134+
135+
var pos = GetGeolocator().GetGeopositionAsync(TimeSpan.FromTicks(0), TimeSpan.FromDays(365));
136+
cancelToken.Value.Register(o => ((IAsyncOperation<Geoposition>)o).Cancel(), pos);
137+
var timer = new eShopOnContainers.Windows.Helpers.Timeout(timeoutMilliseconds, pos.Cancel);
138+
var tcs = new TaskCompletionSource<Position>();
139+
140+
pos.Completed = (op, s) =>
141+
{
142+
timer.Cancel();
143+
144+
switch (s)
145+
{
146+
case AsyncStatus.Canceled:
147+
tcs.SetCanceled();
148+
break;
149+
case AsyncStatus.Completed:
150+
tcs.SetResult(GetPosition(op.GetResults()));
151+
break;
152+
case AsyncStatus.Error:
153+
var ex = op.ErrorCode;
154+
if (ex is UnauthorizedAccessException)
155+
ex = new GeolocationException(GeolocationError.Unauthorized, ex);
156+
157+
tcs.SetException(ex);
158+
break;
159+
}
160+
};
161+
return tcs.Task;
162+
}
163+
164+
#endregion
165+
}
166+
}

src/Mobile/eShopOnContainers/eShopOnContainers.Windows/eShopOnContainers.Windows.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,12 +115,14 @@
115115
<Compile Include="Effects\EntryLineColorEffect.cs" />
116116
<Compile Include="Extensions\VisualTreeExtensions.cs" />
117117
<Compile Include="Helpers\ColorHelper.cs" />
118+
<Compile Include="Helpers\Timeout.cs" />
118119
<Compile Include="MainPage.xaml.cs">
119120
<DependentUpon>MainPage.xaml</DependentUpon>
120121
</Compile>
121122
<Compile Include="Properties\AssemblyInfo.cs" />
122123
<Compile Include="Renderers\CustomTabbedPageRenderer.cs" />
123124
<Compile Include="Renderers\SlideDownMenuPageRenderer.cs" />
125+
<Compile Include="Services\LocationServiceImplementation.cs" />
124126
<Compile Include="Services\SettingsServiceImplementation.cs" />
125127
</ItemGroup>
126128
<ItemGroup>

0 commit comments

Comments
 (0)