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 /// <feature>http://tizen.org/feature/location</feature>
66 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
67 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
68 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
69 public Locator(LocationType locationType)
71 Log.Info(Globals.LogTag, "Locator Constructor");
72 int ret = Interop.Locator.Create((int)locationType, out _handle);
73 if (((LocationError)ret != LocationError.None))
75 Log.Error(Globals.LogTag, "Error creating Location Manager," + (LocationError)ret);
76 throw LocationErrorFactory.ThrowLocationException(ret);
78 _location = new Location();
79 _locationType = locationType;
83 /// The destructor of Locator class.
91 /// The time interval between callback updates.
92 /// Should be in the range [1~120] seconds.
94 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
95 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
100 Log.Info(Globals.LogTag, "Getting the Callback Interval");
105 Log.Info(Globals.LogTag, "Setting the Callback Interval");
106 if (value > 0 && value <= 120)
112 Log.Error(Globals.LogTag, "Error setting Callback Interval");
113 throw LocationErrorFactory.ThrowLocationException((int)LocationError.InvalidParameter);
119 /// The time interval between Distance based location callback updates.
120 /// Should be in the range [1~120] seconds.
122 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
123 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
124 public int StayInterval
128 Log.Info(Globals.LogTag, "Getting the StayInterval");
129 return _stayInterval;
133 Log.Info(Globals.LogTag, "Setting the StayInterval");
134 if (value > 0 && value <= 120)
136 _stayInterval = value;
140 Log.Error(Globals.LogTag, "Error Setting the StayInterval");
141 throw LocationErrorFactory.ThrowLocationException((int)LocationError.InvalidParameter);
147 /// The distance between callback updates.
148 /// Should be in the range [1-120] meters.
150 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
151 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
152 public double Distance
156 Log.Info(Globals.LogTag, "Getting the Distance Interval");
161 Log.Info(Globals.LogTag, "Setting the Distance Interval");
162 if (value > 0 && value <= 120)
168 Log.Error(Globals.LogTag, "Error Setting the Distance");
169 throw LocationErrorFactory.ThrowLocationException((int)LocationError.InvalidParameter);
175 /// Gets the Location object.
177 public Location Location
181 Log.Info(Globals.LogTag, "Getting location details");
187 /// Gets the type used to obtain Location data.
189 public LocationType LocationType
193 Log.Info(Globals.LogTag, "Getting LocationType");
194 return _locationType;
199 /// Gets the status whether mock location is enabled or not.
201 /// <privilege>http://tizen.org/privilege/location</privilege>
202 /// <exception cref="UnauthroizedAccessException">Thrown when the app has no privilege to use the location.</exception>
203 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
204 public bool EnableMock
208 Log.Info(Globals.LogTag, "Getting getting Mock");
209 _isEnableMock = GetEnableMock();
210 return _isEnableMock;
214 _isEnableMock = value;
219 internal IntPtr GetHandle()
224 private bool GetEnableMock()
227 int ret = Interop.Locator.IsEnabledMock(out status);
228 if (((LocationError)ret != LocationError.None))
230 Log.Error(Globals.LogTag, "Error Get Enable Mock Status," + (LocationError)ret);
231 throw LocationErrorFactory.ThrowLocationException(ret);
236 private void SetEnableMock()
238 int ret = Interop.Locator.EnableMock(_isEnableMock);
239 if (((LocationError)ret != LocationError.None))
241 Log.Error(Globals.LogTag, "Error Set Enable Mock Status," + (LocationError)ret);
242 throw LocationErrorFactory.ThrowLocationException(ret);
247 /// Starts the Location Manager which has been created using the specified method.
249 /// <privilege>http://tizen.org/privilege/location</privilege>
250 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
251 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
252 /// <exception cref="UnauthroizedAccessException">Thrown when the app has no privilege to use the location.</exception>
253 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
256 Log.Info(Globals.LogTag, "Starting Location Manager");
257 int ret = Interop.Locator.Start(_handle);
258 if (((LocationError)ret != LocationError.None))
260 Log.Error(Globals.LogTag, "Error Starting Location Manager," + (LocationError)ret);
261 throw LocationErrorFactory.ThrowLocationException(ret);
267 /// Stops the Location Manager which has been activated using the specified method.
268 /// Does not destroy the manager.
270 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
271 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
272 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
275 Log.Info(Globals.LogTag, "Stopping Location Manager");
276 int ret = Interop.Locator.Stop(_handle);
277 if (((LocationError)ret != LocationError.None))
279 Log.Error(Globals.LogTag, "Error stopping Location Manager," + (LocationError)ret);
280 throw LocationErrorFactory.ThrowLocationException(ret);
286 /// Sets a mock location for the given location method.
288 /// <param name="location"> The location object containing the mock location details.</param>
289 /// <privilege>http://tizen.org/privilege/location</privilege>
290 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
291 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
292 /// <exception cref="UnauthroizedAccessException">Thrown when the app has no privilege to use the location.</exception>
293 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
294 public void SetMockLocation(Location location)
296 Log.Info(Globals.LogTag, "Setting mock location");
297 int ret = Interop.Locator.SetMockLocation(_handle, location.Latitude, location.Longitude, location.Altitude, location.Speed, location.Direction, location.Accuracy);
298 if (((LocationError)ret == LocationError.None))
300 _location.Latitude = location.Latitude;
301 _location.Longitude = location.Longitude;
302 _location.Altitude = location.Altitude;
303 _location.Speed = location.Speed;
304 _location.Direction = location.Direction;
305 _location.Accuracy = location.Accuracy;
309 Log.Error(Globals.LogTag, "Error in setting up location mocking," + (LocationError)ret);
310 throw LocationErrorFactory.ThrowLocationException(ret);
315 /// Clears a mock location for the given location method.
317 /// <privilege>http://tizen.org/privilege/location</privilege>
318 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
319 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
320 /// <exception cref="UnauthroizedAccessException">Thrown when the app has no privilege to use the location.</exception>
321 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
322 public void ClearMock()
324 Log.Info(Globals.LogTag, "Clear mock location");
325 int ret = Interop.Locator.ClearMock(_handle);
326 if (((LocationError)ret != LocationError.None))
328 Log.Error(Globals.LogTag, "Error in clear up location mocking," + (LocationError)ret);
329 throw LocationErrorFactory.ThrowLocationException(ret);
334 /// Gets the details of the location asynchronously.
336 /// <param name="timeout"> Timeout to stop requesting single location after(seconds).</param>
337 /// <returns> A task which contains the current location details</returns>
338 /// <privilege>http://tizen.org/privilege/location</privilege>
339 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
340 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
341 /// <exception cref="UnauthroizedAccessException">Thrown when the app has no privilege to use the location.</exception>
342 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
343 public Task<Location> GetLocationAsync(int timeout)
345 var task = new TaskCompletionSource<Location>();
346 IntPtr id = IntPtr.Zero;
349 id = (IntPtr)_requestId++;
350 _callback_map[id] = (LocationError error, double latitude, double longitude, double altitude, int timestamp, double speed, double direction, double climb, IntPtr userData) =>
352 if (error != LocationError.None)
354 Log.Error(Globals.LogTag, "Error in getting up location information," + (LocationError)error);
358 Log.Info(Globals.LogTag, "Creating a current location object");
359 _location = new Location(latitude, longitude, altitude, speed, direction, 0.0, timestamp);
360 task.SetResult(_location);
364 _callback_map.Remove(userData);
369 int ret = Interop.LocatorEvent.GetSingleLocation(_handle, timeout, _callback_map[id], id);
370 if (((LocationError)ret != LocationError.None))
372 Log.Error(Globals.LogTag, "Error in setting up location mocking," + (LocationError)ret);
373 throw LocationErrorFactory.ThrowLocationException(ret);
380 /// Gets the details of the location.
382 /// <returns> which contains the current location details.</returns>
383 /// <privilege>http://tizen.org/privilege/location</privilege>
384 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
385 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
386 /// <exception cref="UnauthroizedAccessException">Thrown when the app has no privilege to use the location.</exception>
387 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
388 public Location GetLocation()
391 double longitude = 0;
395 double direction = 0;
403 Log.Info(Globals.LogTag, "Get current location information");
404 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);
405 if (((LocationError)ret != LocationError.None))
407 Log.Error(Globals.LogTag, "Error in get current location infomation," + (LocationError)ret);
408 throw LocationErrorFactory.ThrowLocationException(ret);
413 Log.Info(Globals.LogTag, "Get last location information");
414 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);
415 if (((LocationError)ret != LocationError.None))
417 Log.Error(Globals.LogTag, "Error in get last location information," + (LocationError)ret);
418 throw LocationErrorFactory.ThrowLocationException(ret);
422 Location location = new Location(latitude, longitude, altitude, speed, direction, accuracy, timestamp);
423 _location = location;
430 /// Adds a bounds for a given locator.
432 /// <param name="locationBoundary"> The boundary object to be added to the locator.</param>
433 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
434 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
435 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
436 public void AddBoundary(LocationBoundary locationBoundary)
438 Log.Info(Globals.LogTag, "AddBoundary called");
440 int ret = Interop.Locator.AddBoundary(_handle, locationBoundary.GetHandle());
441 if ((LocationBoundError)ret != LocationBoundError.None)
443 Log.Error(Globals.LogTag, "Error Adding Boundary," + (LocationBoundError)ret);
444 throw LocationErrorFactory.ThrowLocationBoundaryException(ret);
449 /// Deletes a bounds for a given locator.
451 /// <param name="locationBoundary"> The boundary object to be removed from the locator.</param>
452 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
453 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
454 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
455 public void RemoveBoundary(LocationBoundary locationBoundary)
457 Log.Info(Globals.LogTag, "RemoveBoundary called");
458 int ret = Interop.Locator.RemoveBoundary(_handle, locationBoundary.GetHandle());
459 if ((LocationBoundError)ret != LocationBoundError.None)
461 Log.Error(Globals.LogTag, "Error Removing Boundary," + (LocationBoundError)ret);
462 throw LocationErrorFactory.ThrowLocationBoundaryException(ret);
467 /// The overidden Dispose method of the IDisposable class.
469 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
470 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
471 public void Dispose()
474 GC.SuppressFinalize(this);
477 protected virtual void Dispose(bool disposing)
488 private void DestroyHandle()
490 int ret = Interop.Locator.Destroy(_handle);
491 if (((LocationError)ret != LocationError.None))
493 Log.Error(Globals.LogTag, "Error in Destroy handle, " + (LocationError)ret);
494 throw LocationErrorFactory.ThrowLocationException(ret);
499 /// (event) ServiceStateChanged Event is invoked when the location service state is changed.
501 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
502 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
503 public event EventHandler<ServiceStateChangedEventArgs> ServiceStateChanged
507 Log.Info(Globals.LogTag, "ServiceStateChanged called");
508 if (_serviceStateChanged == null)
510 Log.Info(Globals.LogTag, "Calling function SetServiceStateChangedCallback");
511 SetServiceStateChangedCallback();
513 _serviceStateChanged += value;
517 Log.Info(Globals.LogTag, "Callback removed");
518 _serviceStateChanged -= value;
520 if (_serviceStateChanged == null)
522 Log.Info(Globals.LogTag, "Calling function UnSetServiceStateChangedCallback");
523 UnSetServiceStateChangedCallback();
528 private void SetServiceStateChangedCallback()
530 Log.Info(Globals.LogTag, "Calling Interop.LocatorEvent.SetServiceStateChangedCallback");
531 if (_serviceStateChangedCallback == null)
533 _serviceStateChangedCallback = (state, userData) =>
535 Log.Info(Globals.LogTag, "Inside ServiceStateChangedCallback");
536 _serviceStateChanged?.Invoke(this, new ServiceStateChangedEventArgs(state));
540 int ret = Interop.LocatorEvent.SetServiceStateChangedCallback(_handle, _serviceStateChangedCallback, IntPtr.Zero);
541 if (((LocationError)ret != LocationError.None))
543 Log.Error(Globals.LogTag, "Error in Setting Service State Changed Callback," + (LocationError)ret);
544 throw LocationErrorFactory.ThrowLocationException(ret);
548 private void UnSetServiceStateChangedCallback()
550 Log.Info(Globals.LogTag, "Calling Interop.LocatorEvent.UnSetServiceStateChangedCallback");
551 int ret = Interop.LocatorEvent.UnSetServiceStateChangedCallback(_handle);
552 if (((LocationError)ret != LocationError.None))
554 Log.Error(Globals.LogTag, "Error in UnSetting Service State Changed Callback," + (LocationError)ret);
555 throw LocationErrorFactory.ThrowLocationException(ret);
560 /// (event) ZoneChanged is invoked when the previously set boundary area is entered or left.
562 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
563 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
564 public event EventHandler<ZoneChangedEventArgs> ZoneChanged
568 Log.Info(Globals.LogTag, "ZoneChanged called");
569 if (_zoneChanged == null)
571 Log.Info(Globals.LogTag, "Calling function SetZoneChangedCallback");
572 SetZoneChangedCallback();
574 _zoneChanged += value;
578 Log.Info(Globals.LogTag, "Callback removed");
579 _zoneChanged -= value;
581 if (_zoneChanged == null)
583 Log.Info(Globals.LogTag, "Calling function UnSetZoneChangedCallback");
584 UnSetZoneChangedCallback();
589 private void SetZoneChangedCallback()
591 Log.Info(Globals.LogTag, "Inside SetZoneChangedCallback");
592 if (_zoneChangedCallback == null)
594 _zoneChangedCallback = (state, latitude, longitude, altitude, timestamp, userData) =>
596 Log.Info(Globals.LogTag, "Inside ZoneChangedCallback");
597 DateTime timeStamp = DateTime.Now;
600 DateTime start = DateTime.SpecifyKind(new DateTime(1970, 1, 1).AddSeconds(timestamp), DateTimeKind.Utc);
601 timeStamp = start.ToLocalTime();
603 _zoneChanged?.Invoke(this, new ZoneChangedEventArgs(state, latitude, longitude, altitude, timeStamp));
607 int ret = Interop.LocatorEvent.SetZoneChangedCallback(_handle, _zoneChangedCallback, IntPtr.Zero);
608 if (((LocationError)ret != LocationError.None))
610 Log.Error(Globals.LogTag, "Error in Setting Zone Changed Callback," + (LocationError)ret);
611 throw LocationErrorFactory.ThrowLocationException(ret);
615 private void UnSetZoneChangedCallback()
617 Log.Info(Globals.LogTag, "Inside UnSetZoneChangedCallback");
618 int ret = Interop.LocatorEvent.UnSetZoneChangedCallback(_handle);
619 if (((LocationError)ret != LocationError.None))
621 Log.Error(Globals.LogTag, "Error in UnSetting Zone Changed Callback," + (LocationError)ret);
626 /// (event) SetttingChanged is raised when the location setting is changed.
628 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
629 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
630 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
631 public event EventHandler<SettingChangedEventArgs> SettingChanged
635 Log.Info(Globals.LogTag, "Adding SettingChanged EventHandler");
636 if (_settingChanged == null)
638 Log.Info(Globals.LogTag, "Calling function SetSettingChangedCallback");
639 SetSettingChangedCallback();
641 _settingChanged += value;
645 Log.Info(Globals.LogTag, "Removing SettingChanged EventHandler");
646 _settingChanged -= value;
648 if (_settingChanged == null)
650 Log.Info(Globals.LogTag, "Calling function UnSetSettingChangedCallback");
651 UnSetSettingChangedCallback();
656 private void SetSettingChangedCallback()
658 Log.Info(Globals.LogTag, "Calling SetSettingChangedCallback");
659 if (_settingChangedCallback == null)
661 _settingChangedCallback = (method, enable, userData) =>
663 Log.Info(Globals.LogTag, "Calling SettingChangedCallback");
664 _settingChanged?.Invoke(this, new SettingChangedEventArgs(method, enable));
668 int ret = Interop.LocatorEvent.SetSettingChangedCallback((int)_locationType, _settingChangedCallback, IntPtr.Zero);
669 if (((LocationError)ret != LocationError.None))
671 Log.Error(Globals.LogTag, "Error in Setting Changed Callback," + (LocationError)ret);
672 throw LocationErrorFactory.ThrowLocationException(ret);
676 private void UnSetSettingChangedCallback()
678 Log.Info(Globals.LogTag, "Calling UnSetSettingChangedCallback");
679 int ret = Interop.LocatorEvent.UnSetSettingChangedCallback((int)_locationType);
680 if (((LocationError)ret != LocationError.None))
682 Log.Error(Globals.LogTag, "Error in Unsetting Setting's Callback," + (LocationError)ret);
683 throw LocationErrorFactory.ThrowLocationException(ret);
688 /// (event) DistanceBasedLocationChanged is raised with updated location information.
689 /// The callback will be invoked at minimum interval or minimum distance with updated position information.
691 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
692 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
693 public event EventHandler<LocationChangedEventArgs> DistanceBasedLocationChanged
697 Log.Info(Globals.LogTag, "Adding DistanceBasedLocationChanged EventHandler");
698 //if (_distanceBasedLocationChanged == null)
700 Log.Info(Globals.LogTag, "Calling function SetDistanceBasedLocationChangedCallback");
701 SetDistanceBasedLocationChangedCallback();
703 _distanceBasedLocationChanged += value;
707 Log.Info(Globals.LogTag, "Removing DistanceBasedLocationChanged EventHandler");
708 _distanceBasedLocationChanged -= value;
710 if (_distanceBasedLocationChanged == null)
712 Log.Info(Globals.LogTag, "Calling function UnSetDistanceBasedLocationChangedCallback");
713 UnSetDistanceBasedLocationChangedCallback();
718 private void SetDistanceBasedLocationChangedCallback()
720 Log.Info(Globals.LogTag, "SetDistanceBasedLocationChangedCallback");
721 if (_distanceBasedLocationChangedCallback == null) {
722 _distanceBasedLocationChangedCallback = (latitude, longitude, altitude, speed, direction, accuracy, timestamp, userData) =>
724 Log.Info(Globals.LogTag, "DistanceBasedLocationChangedCallback #1");
725 Location location = new Location(latitude, longitude, altitude, speed, direction, accuracy, timestamp);
726 Log.Info(Globals.LogTag, "DistanceBasedLocationChangedCallback #2");
727 _distanceBasedLocationChanged?.Invoke(this, new LocationChangedEventArgs(location));
728 Log.Info(Globals.LogTag, "DistanceBasedLocationChangedCallback #3");
732 int ret = Interop.LocatorEvent.SetDistanceBasedLocationChangedCallback(_handle, _distanceBasedLocationChangedCallback, _stayInterval, _distance, IntPtr.Zero);
733 if (((LocationError)ret != LocationError.None))
735 Log.Error(Globals.LogTag, "Error in Setting Distance based location changed Callback," + (LocationError)ret);
736 throw LocationErrorFactory.ThrowLocationException(ret);
740 private void UnSetDistanceBasedLocationChangedCallback()
742 Log.Info(Globals.LogTag, "UnSetDistanceBasedLocationChangedCallback");
743 int ret = Interop.LocatorEvent.UnSetDistanceBasedLocationChangedCallback(_handle);
744 if (((LocationError)ret != LocationError.None))
746 Log.Error(Globals.LogTag, "Error in UnSetting Distance based location changed Callback," + (LocationError)ret);
747 throw LocationErrorFactory.ThrowLocationException(ret);
749 _distanceBasedLocationChanged = null;
753 /// (event)LocationUpdated is raised at defined intervals of time with updated location information.
754 /// The callback will be invoked periodically.
756 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
757 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
758 public event EventHandler<LocationChangedEventArgs> LocationChanged
762 Log.Info(Globals.LogTag, "Adding LocationChanged EventHandler");
763 if (_locationChanged == null)
765 Log.Info(Globals.LogTag, "Calling function SetLocationChangedCallback");
766 SetLocationChangedCallback();
768 _locationChanged += value;
772 Log.Info(Globals.LogTag, "Adding LocationChanged EventHandler");
773 _locationChanged -= value;
775 if (_locationChanged == null)
777 Log.Info(Globals.LogTag, "calling function UnSetLocationChangedCallback");
778 UnSetLocationChangedCallback();
783 private void SetLocationChangedCallback()
785 Log.Info(Globals.LogTag, "Calling SetLocationChangedCallback");
787 if (_locationChangedCallback == null) {
788 _locationChangedCallback = (latitude, longitude, altitude, speed, direction, accuracy, timestamp, userData) =>
790 Log.Info(Globals.LogTag, "LocationChangedCallback has been called");
791 Location location = new Location(latitude, longitude, altitude, speed, direction, accuracy, timestamp);
792 _location = location;
793 _locationChanged?.Invoke(this, new LocationChangedEventArgs(location));
797 int ret = Interop.LocatorEvent.SetLocationChangedCallback(_handle, _locationChangedCallback, _interval, IntPtr.Zero);
798 if (((LocationError)ret != LocationError.None))
800 Log.Error(Globals.LogTag, "Error in Setting location changed Callback," + (LocationError)ret);
801 throw LocationErrorFactory.ThrowLocationException(ret);
805 private void UnSetLocationChangedCallback()
807 Log.Info(Globals.LogTag, "Calling UnSetLocationChangedCallback");
808 int ret = Interop.LocatorEvent.UnSetLocationChangedCallback(_handle);
809 if (((LocationError)ret != LocationError.None))
811 Log.Error(Globals.LogTag, "Error in UnSetting location changed Callback," + (LocationError)ret);
812 throw LocationErrorFactory.ThrowLocationException(ret);