2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 using System.Collections.Generic;
19 using System.Threading.Tasks;
20 using Tizen.Internals.Errors;
21 using System.Runtime.InteropServices;
23 namespace Tizen.Location
25 static internal class Globals
27 internal const string LogTag = "Tizen.Location";
31 /// A class which contains the functionality for obtaining geographical infomation and setting boundary condition.
32 /// Notifications on events like service becoming enabled or disabled, new position data being available
33 /// and others can also be acquired.
35 public class Locator : IDisposable
37 private int _interval = 1;
38 private int _stayInterval = 120;
39 private int _requestId = 0;
40 private double _distance = 120.0;
41 private bool _isEnableMock = false;
42 private bool _disposed = false;
43 private bool _isStarted = false;
44 private IntPtr _handle;
45 private LocationType _locationType;
46 private Location _location = null;
47 private Dictionary<IntPtr, Interop.LocatorEvent.LocationUpdatedCallback> _callback_map = new Dictionary<IntPtr, Interop.LocatorEvent.LocationUpdatedCallback>();
49 private Interop.LocatorEvent.ServiceStatechangedCallback _serviceStateChangedCallback;
50 private Interop.LocatorEvent.ZonechangedCallback _zoneChangedCallback;
51 private Interop.LocatorEvent.SettingchangedCallback _settingChangedCallback;
52 private Interop.LocatorEvent.LocationchangedCallback _distanceBasedLocationChangedCallback;
53 private Interop.LocatorEvent.LocationchangedCallback _locationChangedCallback;
55 private EventHandler<ZoneChangedEventArgs> _zoneChanged;
56 private EventHandler<ServiceStateChangedEventArgs> _serviceStateChanged;
57 private EventHandler<SettingChangedEventArgs> _settingChanged;
58 private EventHandler<LocationChangedEventArgs> _distanceBasedLocationChanged;
59 private EventHandler<LocationChangedEventArgs> _locationChanged;
62 /// The constructor of Locator class.
64 /// <param name="locationType"> The back-end positioning method to be used for LBS.</param>
65 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
66 /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
67 /// <exception cref="NotSupportedException">Thrown when the location is not supported</exception>
68 public Locator(LocationType locationType)
70 Log.Info(Globals.LogTag, "Locator Constructor");
71 int ret = Interop.Locator.Create((int)locationType, out _handle);
72 if (((LocationError)ret != LocationError.None))
74 Log.Error(Globals.LogTag, "Error creating Location Manager," + (LocationError)ret);
75 throw LocationErrorFactory.ThrowLocationException(ret);
77 _location = new Location();
78 _locationType = locationType;
82 /// The destructor of Locator class.
90 /// The time interval between callback updates.
91 /// Should be in the range [1~120] seconds.
93 /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
94 /// <exception cref="NotSupportedException">Thrown when the location is not supported</exception>
99 Log.Info(Globals.LogTag, "Getting the Callback Interval");
104 Log.Info(Globals.LogTag, "Setting the Callback Interval");
105 if (value > 0 && value <= 120)
111 Log.Error(Globals.LogTag, "Error setting Callback Interval");
112 throw LocationErrorFactory.ThrowLocationException((int)LocationError.InvalidParameter);
118 /// The time interval between Distance based location callback updates.
119 /// Should be in the range [1~120] seconds.
121 /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
122 /// <exception cref="NotSupportedException">Thrown when the location is not supported</exception>
123 public int StayInterval
127 Log.Info(Globals.LogTag, "Getting the StayInterval");
128 return _stayInterval;
132 Log.Info(Globals.LogTag, "Setting the StayInterval");
133 if (value > 0 && value <= 120)
135 _stayInterval = value;
139 Log.Error(Globals.LogTag, "Error Setting the StayInterval");
140 throw LocationErrorFactory.ThrowLocationException((int)LocationError.InvalidParameter);
146 /// The distance between callback updates.
147 /// Should be in the range [1-120] meters.
149 /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
150 /// <exception cref="NotSupportedException">Thrown when the location is not supported</exception>
151 public double Distance
155 Log.Info(Globals.LogTag, "Getting the Distance Interval");
160 Log.Info(Globals.LogTag, "Setting the Distance Interval");
161 if (value > 0 && value <= 120)
167 Log.Error(Globals.LogTag, "Error Setting the Distance");
168 throw LocationErrorFactory.ThrowLocationException((int)LocationError.InvalidParameter);
174 /// Gets the Location object.
176 public Location Location
180 Log.Info(Globals.LogTag, "Getting location details");
186 /// Gets the type used to obtain Location data.
188 public LocationType LocationType
192 Log.Info(Globals.LogTag, "Getting LocationType");
193 return _locationType;
198 /// Gets the status whether mock location is enabled or not.
200 /// <exception cref="UnauthroizedAccessException">Thrown when the app has no privilege to use the location</exception>
201 /// <exception cref="NotSupportedException">Thrown when the location is not supported</exception>
202 public bool EnableMock
206 Log.Info(Globals.LogTag, "Getting getting Mock");
207 _isEnableMock = GetEnableMock();
208 return _isEnableMock;
212 _isEnableMock = value;
217 internal IntPtr GetHandle()
222 private bool GetEnableMock()
225 int ret = Interop.Locator.IsEnabledMock(out status);
226 if (((LocationError)ret != LocationError.None))
228 Log.Error(Globals.LogTag, "Error Get Enable Mock Status," + (LocationError)ret);
229 throw LocationErrorFactory.ThrowLocationException(ret);
234 private void SetEnableMock()
236 int ret = Interop.Locator.EnableMock(_isEnableMock);
237 if (((LocationError)ret != LocationError.None))
239 Log.Error(Globals.LogTag, "Error Set Enable Mock Status," + (LocationError)ret);
240 throw LocationErrorFactory.ThrowLocationException(ret);
245 /// Starts the Location Manager which has been created using the specified method.
247 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
248 /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
249 /// <exception cref="UnauthroizedAccessException">Thrown when the app has no privilege to use the location</exception>
250 /// <exception cref="NotSupportedException">Thrown when the location is not supported</exception>
253 Log.Info(Globals.LogTag, "Starting Location Manager");
254 int ret = Interop.Locator.Start(_handle);
255 if (((LocationError)ret != LocationError.None))
257 Log.Error(Globals.LogTag, "Error Starting Location Manager," + (LocationError)ret);
258 throw LocationErrorFactory.ThrowLocationException(ret);
264 /// Stops the Location Manager which has been activated using the specified method.
265 /// Does not destroy the manager.
267 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
268 /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
269 /// <exception cref="NotSupportedException">Thrown when the location is not supported</exception>
272 Log.Info(Globals.LogTag, "Stopping Location Manager");
273 int ret = Interop.Locator.Stop(_handle);
274 if (((LocationError)ret != LocationError.None))
276 Log.Error(Globals.LogTag, "Error stopping Location Manager," + (LocationError)ret);
277 throw LocationErrorFactory.ThrowLocationException(ret);
283 /// Sets a mock location for the given location method.
285 /// <param name="location"> The location object containing the mock location details.</param>
286 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
287 /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
288 /// <exception cref="UnauthroizedAccessException">Thrown when the app has no privilege to use the location</exception>
289 /// <exception cref="NotSupportedException">Thrown when the location is not supported</exception>
290 public void SetMockLocation(Location location)
292 Log.Info(Globals.LogTag, "Setting mock location");
293 int ret = Interop.Locator.SetMockLocation(_handle, location.Latitude, location.Longitude, location.Altitude, location.Speed, location.Direction, location.Accuracy);
294 if (((LocationError)ret == LocationError.None))
296 _location.Latitude = location.Latitude;
297 _location.Longitude = location.Longitude;
298 _location.Altitude = location.Altitude;
299 _location.Speed = location.Speed;
300 _location.Direction = location.Direction;
301 _location.Accuracy = location.Accuracy;
305 Log.Error(Globals.LogTag, "Error in setting up location mocking," + (LocationError)ret);
306 throw LocationErrorFactory.ThrowLocationException(ret);
311 /// Clears a mock location for the given location method.
313 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
314 /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
315 /// <exception cref="UnauthroizedAccessException">Thrown when the app has no privilege to use the location</exception>
316 /// <exception cref="NotSupportedException">Thrown when the location is not supported</exception>
317 public void ClearMock()
319 Log.Info(Globals.LogTag, "Clear mock location");
320 int ret = Interop.Locator.ClearMock(_handle);
321 if (((LocationError)ret != LocationError.None))
323 Log.Error(Globals.LogTag, "Error in clear up location mocking," + (LocationError)ret);
324 throw LocationErrorFactory.ThrowLocationException(ret);
329 /// Gets the details of the location asynchronously.
331 /// <param name="timeout"> Timeout to stop requesting single location after(seconds).</param>
332 /// <returns> A task which contains the current location details</returns>
333 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
334 /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
335 /// <exception cref="UnauthroizedAccessException">Thrown when the app has no privilege to use the location</exception>
336 /// <exception cref="NotSupportedException">Thrown when the location is not supported</exception>
337 public Task<Location> GetLocationAsync(int timeout)
339 var task = new TaskCompletionSource<Location>();
340 IntPtr id = IntPtr.Zero;
343 id = (IntPtr)_requestId++;
344 _callback_map[id] = (LocationError error, double latitude, double longitude, double altitude, int timestamp, double speed, double direction, double climb, IntPtr userData) =>
346 if (error != LocationError.None)
348 Log.Error(Globals.LogTag, "Error in getting up location information," + (LocationError)error);
352 Log.Info(Globals.LogTag, "Creating a current location object");
353 _location = new Location(latitude, longitude, altitude, speed, direction, 0.0, timestamp);
354 task.SetResult(_location);
358 _callback_map.Remove(userData);
363 int ret = Interop.LocatorEvent.GetSingleLocation(_handle, timeout, _callback_map[id], id);
364 if (((LocationError)ret != LocationError.None))
366 Log.Error(Globals.LogTag, "Error in setting up location mocking," + (LocationError)ret);
367 throw LocationErrorFactory.ThrowLocationException(ret);
374 /// Gets the details of the location.
376 /// <returns> which contains the current location details</returns>
377 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
378 /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
379 /// <exception cref="UnauthroizedAccessException">Thrown when the app has no privilege to use the location</exception>
380 /// <exception cref="NotSupportedException">Thrown when the location is not supported</exception>
381 public Location GetLocation()
384 double longitude = 0;
388 double direction = 0;
396 Log.Info(Globals.LogTag, "Get current location information");
397 int ret = Interop.Locator.GetLocation(_handle, out altitude, out latitude, out longitude, out climb, out direction, out speed, out level, out accuracy, out vertical, out timestamp);
398 if (((LocationError)ret != LocationError.None))
400 Log.Error(Globals.LogTag, "Error in get current location infomation," + (LocationError)ret);
401 throw LocationErrorFactory.ThrowLocationException(ret);
406 Log.Info(Globals.LogTag, "Get last location information");
407 int ret = Interop.Locator.GetLastLocation(_handle, out altitude, out latitude, out longitude, out climb, out direction, out speed, out level, out accuracy, out vertical, out timestamp);
408 if (((LocationError)ret != LocationError.None))
410 Log.Error(Globals.LogTag, "Error in get last location information," + (LocationError)ret);
411 throw LocationErrorFactory.ThrowLocationException(ret);
415 Location location = new Location(latitude, longitude, altitude, speed, direction, accuracy, timestamp);
416 _location = location;
423 /// Adds a bounds for a given locator.
425 /// <param name="locationBoundary"> The boundary object to be added to the locator.</param>
426 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
427 /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
428 /// <exception cref="NotSupportedException">Thrown when the location is not supported</exception>
429 public void AddBoundary(LocationBoundary locationBoundary)
431 Log.Info(Globals.LogTag, "AddBoundary called");
433 int ret = Interop.Locator.AddBoundary(_handle, locationBoundary.GetHandle());
434 if ((LocationBoundError)ret != LocationBoundError.None)
436 Log.Error(Globals.LogTag, "Error Adding Boundary," + (LocationBoundError)ret);
437 throw LocationErrorFactory.ThrowLocationBoundaryException(ret);
442 /// Deletes a bounds for a given locator.
444 /// <param name="locationBoundary"> The boundary object to be removed from the locator.</param>
445 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
446 /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
447 /// <exception cref="NotSupportedException">Thrown when the location is not supported</exception>
448 public void RemoveBoundary(LocationBoundary locationBoundary)
450 Log.Info(Globals.LogTag, "RemoveBoundary called");
451 int ret = Interop.Locator.RemoveBoundary(_handle, locationBoundary.GetHandle());
452 if ((LocationBoundError)ret != LocationBoundError.None)
454 Log.Error(Globals.LogTag, "Error Removing Boundary," + (LocationBoundError)ret);
455 throw LocationErrorFactory.ThrowLocationBoundaryException(ret);
460 /// The overidden Dispose method of the IDisposable class.
462 /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
463 /// <exception cref="NotSupportedException">Thrown when the location is not supported</exception>
464 public void Dispose()
467 GC.SuppressFinalize(this);
470 protected virtual void Dispose(bool disposing)
481 private void DestroyHandle()
483 int ret = Interop.Locator.Destroy(_handle);
484 if (((LocationError)ret != LocationError.None))
486 Log.Error(Globals.LogTag, "Error in Destroy handle, " + (LocationError)ret);
487 throw LocationErrorFactory.ThrowLocationException(ret);
492 /// (event) ServiceStateChanged Event is invoked when the location service state is changed.
494 /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
495 /// <exception cref="NotSupportedException">Thrown when the location is not supported</exception>
496 public event EventHandler<ServiceStateChangedEventArgs> ServiceStateChanged
500 Log.Info(Globals.LogTag, "ServiceStateChanged called");
501 if (_serviceStateChanged == null)
503 Log.Info(Globals.LogTag, "Calling function SetServiceStateChangedCallback");
504 SetServiceStateChangedCallback();
506 _serviceStateChanged += value;
510 Log.Info(Globals.LogTag, "Callback removed");
511 _serviceStateChanged -= value;
513 if (_serviceStateChanged == null)
515 Log.Info(Globals.LogTag, "Calling function UnSetServiceStateChangedCallback");
516 UnSetServiceStateChangedCallback();
521 private void SetServiceStateChangedCallback()
523 Log.Info(Globals.LogTag, "Calling Interop.LocatorEvent.SetServiceStateChangedCallback");
524 if (_serviceStateChangedCallback == null)
526 _serviceStateChangedCallback = (state, userData) =>
528 Log.Info(Globals.LogTag, "Inside ServiceStateChangedCallback");
529 _serviceStateChanged?.Invoke(this, new ServiceStateChangedEventArgs(state));
533 int ret = Interop.LocatorEvent.SetServiceStateChangedCallback(_handle, _serviceStateChangedCallback, IntPtr.Zero);
534 if (((LocationError)ret != LocationError.None))
536 Log.Error(Globals.LogTag, "Error in Setting Service State Changed Callback," + (LocationError)ret);
537 throw LocationErrorFactory.ThrowLocationException(ret);
541 private void UnSetServiceStateChangedCallback()
543 Log.Info(Globals.LogTag, "Calling Interop.LocatorEvent.UnSetServiceStateChangedCallback");
544 int ret = Interop.LocatorEvent.UnSetServiceStateChangedCallback(_handle);
545 if (((LocationError)ret != LocationError.None))
547 Log.Error(Globals.LogTag, "Error in UnSetting Service State Changed Callback," + (LocationError)ret);
548 throw LocationErrorFactory.ThrowLocationException(ret);
553 /// (event) ZoneChanged is invoked when the previously set boundary area is entered or left.
555 /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
556 /// <exception cref="NotSupportedException">Thrown when the location is not supported</exception>
557 public event EventHandler<ZoneChangedEventArgs> ZoneChanged
561 Log.Info(Globals.LogTag, "ZoneChanged called");
562 if (_zoneChanged == null)
564 Log.Info(Globals.LogTag, "Calling function SetZoneChangedCallback");
565 SetZoneChangedCallback();
567 _zoneChanged += value;
571 Log.Info(Globals.LogTag, "Callback removed");
572 _zoneChanged -= value;
574 if (_zoneChanged == null)
576 Log.Info(Globals.LogTag, "Calling function UnSetZoneChangedCallback");
577 UnSetZoneChangedCallback();
582 private void SetZoneChangedCallback()
584 Log.Info(Globals.LogTag, "Inside SetZoneChangedCallback");
585 if (_zoneChangedCallback == null)
587 _zoneChangedCallback = (state, latitude, longitude, altitude, timestamp, userData) =>
589 Log.Info(Globals.LogTag, "Inside ZoneChangedCallback");
590 DateTime timeStamp = DateTime.Now;
593 DateTime start = DateTime.SpecifyKind(new DateTime(1970, 1, 1).AddSeconds(timestamp), DateTimeKind.Utc);
594 timeStamp = start.ToLocalTime();
596 _zoneChanged?.Invoke(this, new ZoneChangedEventArgs(state, latitude, longitude, altitude, timeStamp));
600 int ret = Interop.LocatorEvent.SetZoneChangedCallback(_handle, _zoneChangedCallback, IntPtr.Zero);
601 if (((LocationError)ret != LocationError.None))
603 Log.Error(Globals.LogTag, "Error in Setting Zone Changed Callback," + (LocationError)ret);
604 throw LocationErrorFactory.ThrowLocationException(ret);
608 private void UnSetZoneChangedCallback()
610 Log.Info(Globals.LogTag, "Inside UnSetZoneChangedCallback");
611 int ret = Interop.LocatorEvent.UnSetZoneChangedCallback(_handle);
612 if (((LocationError)ret != LocationError.None))
614 Log.Error(Globals.LogTag, "Error in UnSetting Zone Changed Callback," + (LocationError)ret);
619 /// (event) SetttingChanged is raised when the location setting is changed.
621 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state</exception>
622 /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
623 /// <exception cref="NotSupportedException">Thrown when the location is not supported</exception>
624 public event EventHandler<SettingChangedEventArgs> SettingChanged
628 Log.Info(Globals.LogTag, "Adding SettingChanged EventHandler");
629 if (_settingChanged == null)
631 Log.Info(Globals.LogTag, "Calling function SetSettingChangedCallback");
632 SetSettingChangedCallback();
634 _settingChanged += value;
638 Log.Info(Globals.LogTag, "Removing SettingChanged EventHandler");
639 _settingChanged -= value;
641 if (_settingChanged == null)
643 Log.Info(Globals.LogTag, "Calling function UnSetSettingChangedCallback");
644 UnSetSettingChangedCallback();
649 private void SetSettingChangedCallback()
651 Log.Info(Globals.LogTag, "Calling SetSettingChangedCallback");
652 if (_settingChangedCallback == null)
654 _settingChangedCallback = (method, enable, userData) =>
656 Log.Info(Globals.LogTag, "Calling SettingChangedCallback");
657 _settingChanged?.Invoke(this, new SettingChangedEventArgs(method, enable));
661 int ret = Interop.LocatorEvent.SetSettingChangedCallback((int)_locationType, _settingChangedCallback, IntPtr.Zero);
662 if (((LocationError)ret != LocationError.None))
664 Log.Error(Globals.LogTag, "Error in Setting Changed Callback," + (LocationError)ret);
665 throw LocationErrorFactory.ThrowLocationException(ret);
669 private void UnSetSettingChangedCallback()
671 Log.Info(Globals.LogTag, "Calling UnSetSettingChangedCallback");
672 int ret = Interop.LocatorEvent.UnSetSettingChangedCallback((int)_locationType);
673 if (((LocationError)ret != LocationError.None))
675 Log.Error(Globals.LogTag, "Error in Unsetting Setting's Callback," + (LocationError)ret);
676 throw LocationErrorFactory.ThrowLocationException(ret);
681 /// (event) DistanceBasedLocationChanged is raised with updated location information.
682 /// The callback will be invoked at minimum interval or minimum distance with updated position information.
684 /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
685 /// <exception cref="NotSupportedException">Thrown when the location is not supported</exception>
686 public event EventHandler<LocationChangedEventArgs> DistanceBasedLocationChanged
690 Log.Info(Globals.LogTag, "Adding DistanceBasedLocationChanged EventHandler");
691 //if (_distanceBasedLocationChanged == null)
693 Log.Info(Globals.LogTag, "Calling function SetDistanceBasedLocationChangedCallback");
694 SetDistanceBasedLocationChangedCallback();
696 _distanceBasedLocationChanged += value;
700 Log.Info(Globals.LogTag, "Removing DistanceBasedLocationChanged EventHandler");
701 _distanceBasedLocationChanged -= value;
703 if (_distanceBasedLocationChanged == null)
705 Log.Info(Globals.LogTag, "Calling function UnSetDistanceBasedLocationChangedCallback");
706 UnSetDistanceBasedLocationChangedCallback();
711 private void SetDistanceBasedLocationChangedCallback()
713 Log.Info(Globals.LogTag, "SetDistanceBasedLocationChangedCallback");
714 if (_distanceBasedLocationChangedCallback == null) {
715 _distanceBasedLocationChangedCallback = (latitude, longitude, altitude, speed, direction, accuracy, timestamp, userData) =>
717 Log.Info(Globals.LogTag, "DistanceBasedLocationChangedCallback #1");
718 Location location = new Location(latitude, longitude, altitude, speed, direction, accuracy, timestamp);
719 Log.Info(Globals.LogTag, "DistanceBasedLocationChangedCallback #2");
720 _distanceBasedLocationChanged?.Invoke(this, new LocationChangedEventArgs(location));
721 Log.Info(Globals.LogTag, "DistanceBasedLocationChangedCallback #3");
725 int ret = Interop.LocatorEvent.SetDistanceBasedLocationChangedCallback(_handle, _distanceBasedLocationChangedCallback, _stayInterval, _distance, IntPtr.Zero);
726 if (((LocationError)ret != LocationError.None))
728 Log.Error(Globals.LogTag, "Error in Setting Distance based location changed Callback," + (LocationError)ret);
729 throw LocationErrorFactory.ThrowLocationException(ret);
733 private void UnSetDistanceBasedLocationChangedCallback()
735 Log.Info(Globals.LogTag, "UnSetDistanceBasedLocationChangedCallback");
736 int ret = Interop.LocatorEvent.UnSetDistanceBasedLocationChangedCallback(_handle);
737 if (((LocationError)ret != LocationError.None))
739 Log.Error(Globals.LogTag, "Error in UnSetting Distance based location changed Callback," + (LocationError)ret);
740 throw LocationErrorFactory.ThrowLocationException(ret);
742 _distanceBasedLocationChanged = null;
746 /// (event)LocationUpdated is raised at defined intervals of time with updated location information.
747 /// The callback will be invoked periodically.
749 /// <exception cref="ArgumentException">Thrown when an invalid argument is used</exception>
750 /// <exception cref="NotSupportedException">Thrown when the location is not supported</exception>
751 public event EventHandler<LocationChangedEventArgs> LocationChanged
755 Log.Info(Globals.LogTag, "Adding LocationChanged EventHandler");
756 if (_locationChanged == null)
758 Log.Info(Globals.LogTag, "Calling function SetLocationChangedCallback");
759 SetLocationChangedCallback();
761 _locationChanged += value;
765 Log.Info(Globals.LogTag, "Adding LocationChanged EventHandler");
766 _locationChanged -= value;
768 if (_locationChanged == null)
770 Log.Info(Globals.LogTag, "calling function UnSetLocationChangedCallback");
771 UnSetLocationChangedCallback();
776 private void SetLocationChangedCallback()
778 Log.Info(Globals.LogTag, "Calling SetLocationChangedCallback");
780 if (_locationChangedCallback == null) {
781 _locationChangedCallback = (latitude, longitude, altitude, speed, direction, accuracy, timestamp, userData) =>
783 Log.Info(Globals.LogTag, "LocationChangedCallback has been called");
784 Location location = new Location(latitude, longitude, altitude, speed, direction, accuracy, timestamp);
785 _location = location;
786 _locationChanged?.Invoke(this, new LocationChangedEventArgs(location));
790 int ret = Interop.LocatorEvent.SetLocationChangedCallback(_handle, _locationChangedCallback, _interval, IntPtr.Zero);
791 if (((LocationError)ret != LocationError.None))
793 Log.Error(Globals.LogTag, "Error in Setting location changed Callback," + (LocationError)ret);
794 throw LocationErrorFactory.ThrowLocationException(ret);
798 private void UnSetLocationChangedCallback()
800 Log.Info(Globals.LogTag, "Calling UnSetLocationChangedCallback");
801 int ret = Interop.LocatorEvent.UnSetLocationChangedCallback(_handle);
802 if (((LocationError)ret != LocationError.None))
804 Log.Error(Globals.LogTag, "Error in UnSetting location changed Callback," + (LocationError)ret);
805 throw LocationErrorFactory.ThrowLocationException(ret);