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 /// This class contains the functionality for obtaining the geographical information and setting the 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 /// <since_tizen> 3 </since_tizen>
36 public class Locator : IDisposable
38 private int _interval = 1;
39 private int _stayInterval = 120;
40 private int _batchInterval = 0;
41 private int _batchPeriod = 0;
42 private int _requestId = 0;
43 private double _distance = 120.0;
44 private bool _isEnableMock = false;
45 private bool _disposed = false;
46 private bool _isBatchStarted;
47 private IntPtr _handle;
48 private LocationType _locationType;
49 private Location _location = null;
50 private Dictionary<IntPtr, Interop.LocatorEvent.LocationUpdatedCallback> _callback_map = new Dictionary<IntPtr, Interop.LocatorEvent.LocationUpdatedCallback>();
52 private Interop.LocatorEvent.ServiceStatechangedCallback _serviceStateChangedCallback;
53 private Interop.LocatorEvent.ZonechangedCallback _zoneChangedCallback;
54 private Interop.LocatorEvent.SettingchangedCallback _settingChangedCallback;
55 private Interop.LocatorEvent.LocationchangedCallback _distanceBasedLocationChangedCallback;
56 private Interop.LocatorEvent.LocationchangedCallback _locationChangedCallback;
57 private Interop.LocatorEvent.LocationBatchCallback _locationBatchCallback;
58 private Interop.LocatorEvent.LocationBatchGetCallback _locationBatchGetCallback;
60 private EventHandler<ZoneChangedEventArgs> _zoneChanged;
61 private EventHandler<ServiceStateChangedEventArgs> _serviceStateChanged;
62 private EventHandler<SettingChangedEventArgs> _settingChanged;
63 private EventHandler<LocationChangedEventArgs> _distanceBasedLocationChanged;
64 private EventHandler<LocationChangedEventArgs> _locationChanged;
67 /// The constructor of the Locator class.
69 /// <since_tizen> 3 </since_tizen>
70 /// <param name="locationType"> The back-end positioning method to be used for LBS.</param>
71 /// <feature>http://tizen.org/feature/location.gps</feature>
72 /// <feature>http://tizen.org/feature/location.wps</feature>
73 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
74 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
75 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
76 public Locator(LocationType locationType)
78 Log.Info(Globals.LogTag, "Locator Constructor");
79 int ret = Interop.Locator.Create((int)locationType, out _handle);
80 if (((LocationError)ret != LocationError.None))
82 Log.Error(Globals.LogTag, "Error creating Location Manager," + (LocationError)ret);
83 throw LocationErrorFactory.ThrowLocationException(ret);
85 _location = new Location();
86 _locationType = locationType;
90 /// The destructor of the Locator class.
92 /// <since_tizen> 3 </since_tizen>
99 /// The time interval between callback updates.
100 /// Should be in the range of 1~120 seconds.
102 /// <since_tizen> 3 </since_tizen>
103 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
108 Log.Info(Globals.LogTag, "Getting the Callback Interval");
113 Log.Info(Globals.LogTag, "Setting the Callback Interval");
114 if (value > 0 && value <= 120)
120 Log.Error(Globals.LogTag, "Error setting Callback Interval");
121 throw LocationErrorFactory.ThrowLocationException((int)LocationError.InvalidParameter);
127 /// The time interval between the distance-based location callback updates.
128 /// Should be in the range of 1~120 seconds.
130 /// <since_tizen> 3 </since_tizen>
131 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
132 public int StayInterval
136 Log.Info(Globals.LogTag, "Getting the StayInterval");
137 return _stayInterval;
141 Log.Info(Globals.LogTag, "Setting the StayInterval");
142 if (value > 0 && value <= 120)
144 _stayInterval = value;
148 Log.Error(Globals.LogTag, "Error Setting the StayInterval");
149 throw LocationErrorFactory.ThrowLocationException((int)LocationError.InvalidParameter);
155 /// The time interval between the position collection in batch mode.
156 /// Should be in the range of 1~255 seconds.
158 /// <since_tizen> 4 </since_tizen>
159 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
160 public int BatchInterval
164 Log.Info(Globals.LogTag, "Getting the Batch Interval");
165 return _batchInterval;
169 Log.Info(Globals.LogTag, "Setting the Batch Interval");
170 if (value > 0 && value <= 255)
172 _batchInterval = value;
176 Log.Error(Globals.LogTag, "Error setting Callback Interval");
177 throw LocationErrorFactory.ThrowLocationException((int)LocationError.InvalidParameter);
183 /// The time interval between batch callback updates. The BatchPeriod should be greater than or equal to the BatchInterval. If the BatchPeriod is zero or smaller than the BatchInterval, then the batch mode will not work. In addition, sometimes the period may not work as you intended, the maximum permissible value for the batch period is device specific.
184 /// Should be in the range of 0~60000 seconds.
186 /// <since_tizen> 4 </since_tizen>
187 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
188 public int BatchPeriod
192 Log.Info(Globals.LogTag, "Getting the Batch Period");
197 Log.Info(Globals.LogTag, "Setting the Batch Period");
198 if (value >= 0 && value <= 60000)
200 _batchPeriod = value;
204 Log.Error(Globals.LogTag, "Error setting Batch Period");
205 throw LocationErrorFactory.ThrowLocationException((int)LocationError.InvalidParameter);
211 /// The distance between callback updates.
212 /// Should be in the range of 1-120 meters.
214 /// <since_tizen> 3 </since_tizen>
215 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
216 public double Distance
220 Log.Info(Globals.LogTag, "Getting the Distance Interval");
225 Log.Info(Globals.LogTag, "Setting the Distance Interval");
226 if (value > 0 && value <= 120)
232 Log.Error(Globals.LogTag, "Error Setting the Distance");
233 throw LocationErrorFactory.ThrowLocationException((int)LocationError.InvalidParameter);
239 /// Gets the location object.
241 /// <since_tizen> 3 </since_tizen>
242 public Location Location
246 Log.Info(Globals.LogTag, "Getting location details");
252 /// Gets the type used to obtain the location data.
254 /// <since_tizen> 3 </since_tizen>
255 public LocationType LocationType
259 Log.Info(Globals.LogTag, "Getting LocationType");
260 return _locationType;
265 /// Gets the status whether the mock location is enabled or not.
267 /// <since_tizen> 3 </since_tizen>
268 /// <privilege>http://tizen.org/privilege/location</privilege>
269 /// <exception cref="UnauthorizedAccessException">Thrown when the application has no privilege to use the location.</exception>
270 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
271 public bool EnableMock
275 Log.Info(Globals.LogTag, "Getting getting Mock");
276 _isEnableMock = GetEnableMock();
277 return _isEnableMock;
281 _isEnableMock = value;
286 internal IntPtr GetHandle()
291 private bool GetEnableMock()
294 int ret = Interop.Locator.IsEnabledMock(out status);
295 if (((LocationError)ret != LocationError.None))
297 Log.Error(Globals.LogTag, "Error Get Enable Mock Status," + (LocationError)ret);
298 throw LocationErrorFactory.ThrowLocationException(ret);
303 private void SetEnableMock()
305 int ret = Interop.Locator.EnableMock(_isEnableMock);
306 if (((LocationError)ret != LocationError.None))
308 Log.Error(Globals.LogTag, "Error Set Enable Mock Status," + (LocationError)ret);
309 throw LocationErrorFactory.ThrowLocationException(ret);
314 /// Starts the Location Manager which has been created using the specified method.
316 /// <since_tizen> 3 </since_tizen>
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="UnauthorizedAccessException">Thrown when the application has no privilege to use the location.</exception>
321 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
324 Log.Info(Globals.LogTag, "Starting Location Manager");
325 _isBatchStarted = (_batchPeriod > 0 ) && (_batchPeriod > _batchInterval);
328 int ret = Interop.Locator.StartBatch(_handle);
329 if (((LocationError)ret != LocationError.None))
331 Log.Error(Globals.LogTag, "Error Starting Location Batch mode," + (LocationError)ret);
332 throw LocationErrorFactory.ThrowLocationException(ret);
337 int ret = Interop.Locator.Start(_handle);
338 if (((LocationError)ret != LocationError.None))
340 Log.Error(Globals.LogTag, "Error Starting Location Manager," + (LocationError)ret);
341 throw LocationErrorFactory.ThrowLocationException(ret);
347 /// Stops the Location Manager which has been activated using the specified method.
348 /// Does not destroy the manager.
350 /// <since_tizen> 3 </since_tizen>
351 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
352 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
353 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
356 Log.Info(Globals.LogTag, "Stopping Location Manager");
359 int ret = Interop.Locator.StopBatch(_handle);
360 if (((LocationError)ret != LocationError.None))
362 Log.Error(Globals.LogTag, "Error Stopping Location Batch mode," + (LocationError)ret);
363 throw LocationErrorFactory.ThrowLocationException(ret);
368 int ret = Interop.Locator.Stop(_handle);
369 if (((LocationError)ret != LocationError.None))
371 Log.Error(Globals.LogTag, "Error stopping Location Manager," + (LocationError)ret);
372 throw LocationErrorFactory.ThrowLocationException(ret);
378 /// Sets a mock location for the given location method.
380 /// <since_tizen> 3 </since_tizen>
381 /// <param name="location"> The location object containing the mock location details.</param>
382 /// <privilege>http://tizen.org/privilege/location</privilege>
383 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
384 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
385 /// <exception cref="UnauthorizedAccessException">Thrown when the application has no privilege to use the location.</exception>
386 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
387 public void SetMockLocation(Location location)
389 Log.Info(Globals.LogTag, "Setting mock location");
390 int ret = Interop.Locator.SetMockLocation(_handle, location.Latitude, location.Longitude, location.Altitude, location.Speed, location.Direction, location.Accuracy);
391 if (((LocationError)ret == LocationError.None))
393 _location.Latitude = location.Latitude;
394 _location.Longitude = location.Longitude;
395 _location.Altitude = location.Altitude;
396 _location.Speed = location.Speed;
397 _location.Direction = location.Direction;
398 _location.Accuracy = location.Accuracy;
402 Log.Error(Globals.LogTag, "Error in setting up location mocking," + (LocationError)ret);
403 throw LocationErrorFactory.ThrowLocationException(ret);
408 /// Clears a mock location for the given location method.
410 /// <since_tizen> 3 </since_tizen>
411 /// <privilege>http://tizen.org/privilege/location</privilege>
412 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
413 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
414 /// <exception cref="UnauthorizedAccessException">Thrown when the application has no privilege to use the location.</exception>
415 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
416 public void ClearMock()
418 Log.Info(Globals.LogTag, "Clear mock location");
419 int ret = Interop.Locator.ClearMock(_handle);
420 if (((LocationError)ret != LocationError.None))
422 Log.Error(Globals.LogTag, "Error in clear up location mocking," + (LocationError)ret);
423 throw LocationErrorFactory.ThrowLocationException(ret);
428 /// Gets the details of the location asynchronously.
430 /// <since_tizen> 3 </since_tizen>
431 /// <param name="timeout"> Timeout to stop requesting a single location after (seconds).</param>
432 /// <returns> A task which contains the current location details.</returns>
433 /// <privilege>http://tizen.org/privilege/location</privilege>
434 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
435 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
436 /// <exception cref="UnauthorizedAccessException">Thrown when the application has no privilege to use the location.</exception>
437 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
438 public Task<Location> GetLocationAsync(int timeout)
440 var task = new TaskCompletionSource<Location>();
441 IntPtr id = IntPtr.Zero;
444 id = (IntPtr)_requestId++;
445 _callback_map[id] = (LocationError error, double latitude, double longitude, double altitude, int timestamp, double speed, double direction, double climb, IntPtr userData) =>
447 if (error != LocationError.None)
449 Log.Error(Globals.LogTag, "Error in getting up location information," + (LocationError)error);
453 Log.Info(Globals.LogTag, "Creating a current location object");
454 _location = new Location(latitude, longitude, altitude, speed, direction, 0.0, timestamp);
455 task.SetResult(_location);
459 _callback_map.Remove(userData);
464 int ret = Interop.LocatorEvent.GetSingleLocation(_handle, timeout, _callback_map[id], id);
465 if (((LocationError)ret != LocationError.None))
467 Log.Error(Globals.LogTag, "Error in setting up location mocking," + (LocationError)ret);
468 throw LocationErrorFactory.ThrowLocationException(ret);
475 /// Gets the details of the location.
477 /// <since_tizen> 3 </since_tizen>
478 /// <returns> Which contains the current location details.</returns>
479 /// <privilege>http://tizen.org/privilege/location</privilege>
480 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
481 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
482 /// <exception cref="UnauthorizedAccessException">Thrown when the application has no privilege to use the location.</exception>
483 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
484 public Location GetLocation()
487 double longitude = 0;
491 double direction = 0;
497 Log.Info(Globals.LogTag, "Get current location information");
498 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);
499 if (((LocationError)ret != LocationError.None))
501 if ((LocationError)ret == LocationError.ServiceNotAvailable)
503 Log.Info(Globals.LogTag, "Get last location information");
504 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);
505 if (((LocationError)ret != LocationError.None))
507 Log.Error(Globals.LogTag, "Error in get last location information," + (LocationError)ret);
508 throw LocationErrorFactory.ThrowLocationException(ret);
512 if (latitude == 0.0 && longitude == 0.0)
514 Log.Error(Globals.LogTag, "Error fail to get last location information");
515 throw LocationErrorFactory.ThrowLocationException((int)LocationError.ServiceNotAvailable);
521 Log.Error(Globals.LogTag, "Error in get current location information," + (LocationError)ret);
522 throw LocationErrorFactory.ThrowLocationException(ret);
526 Location location = new Location(latitude, longitude, altitude, speed, direction, accuracy, timestamp);
527 _location = location;
534 /// Adds a bound for a given locator.
536 /// <since_tizen> 3 </since_tizen>
537 /// <param name="locationBoundary">The boundary object to be added to the locator.</param>
538 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
539 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
540 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
541 public void AddBoundary(LocationBoundary locationBoundary)
543 Log.Info(Globals.LogTag, "AddBoundary called");
545 int ret = Interop.Locator.AddBoundary(_handle, locationBoundary.GetHandle());
546 if ((LocationBoundError)ret != LocationBoundError.None)
548 Log.Error(Globals.LogTag, "Error Adding Boundary," + (LocationBoundError)ret);
549 throw LocationErrorFactory.ThrowLocationBoundaryException(ret);
554 /// Deletes a bound for a given locator.
556 /// <since_tizen> 3 </since_tizen>
557 /// <param name="locationBoundary"> The boundary object to be removed from the locator.</param>
558 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
559 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
560 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
561 public void RemoveBoundary(LocationBoundary locationBoundary)
563 Log.Info(Globals.LogTag, "RemoveBoundary called");
564 int ret = Interop.Locator.RemoveBoundary(_handle, locationBoundary.GetHandle());
565 if ((LocationBoundError)ret != LocationBoundError.None)
567 Log.Error(Globals.LogTag, "Error Removing Boundary," + (LocationBoundError)ret);
568 throw LocationErrorFactory.ThrowLocationBoundaryException(ret);
573 /// The overidden Dispose method of the IDisposable class.
575 /// <since_tizen> 3 </since_tizen>
576 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
577 public void Dispose()
580 GC.SuppressFinalize(this);
586 /// <since_tizen> 3 </since_tizen>
587 protected virtual void Dispose(bool disposing)
598 private void DestroyHandle()
600 int ret = Interop.Locator.Destroy(_handle);
601 if (((LocationError)ret != LocationError.None))
603 Log.Error(Globals.LogTag, "Error in Destroy handle, " + (LocationError)ret);
604 throw LocationErrorFactory.ThrowLocationException(ret);
609 /// The ServiceStateChanged event is invoked when the location service state is changed.
611 /// <since_tizen> 3 </since_tizen>
612 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
613 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
614 public event EventHandler<ServiceStateChangedEventArgs> ServiceStateChanged
618 Log.Info(Globals.LogTag, "ServiceStateChanged called");
619 if (_serviceStateChanged == null)
621 Log.Info(Globals.LogTag, "Calling function SetServiceStateChangedCallback");
622 SetServiceStateChangedCallback();
624 _serviceStateChanged += value;
628 Log.Info(Globals.LogTag, "Callback removed");
629 _serviceStateChanged -= value;
631 if (_serviceStateChanged == null)
633 Log.Info(Globals.LogTag, "Calling function UnSetServiceStateChangedCallback");
634 UnSetServiceStateChangedCallback();
639 private void SetServiceStateChangedCallback()
641 Log.Info(Globals.LogTag, "Calling Interop.LocatorEvent.SetServiceStateChangedCallback");
642 if (_serviceStateChangedCallback == null)
644 _serviceStateChangedCallback = (state, userData) =>
646 Log.Info(Globals.LogTag, "Inside ServiceStateChangedCallback");
647 _serviceStateChanged?.Invoke(this, new ServiceStateChangedEventArgs(state));
651 int ret = Interop.LocatorEvent.SetServiceStateChangedCallback(_handle, _serviceStateChangedCallback, IntPtr.Zero);
652 if (((LocationError)ret != LocationError.None))
654 Log.Error(Globals.LogTag, "Error in Setting Service State Changed Callback," + (LocationError)ret);
655 throw LocationErrorFactory.ThrowLocationException(ret);
659 private void UnSetServiceStateChangedCallback()
661 Log.Info(Globals.LogTag, "Calling Interop.LocatorEvent.UnSetServiceStateChangedCallback");
662 int ret = Interop.LocatorEvent.UnSetServiceStateChangedCallback(_handle);
663 if (((LocationError)ret != LocationError.None))
665 Log.Error(Globals.LogTag, "Error in UnSetting Service State Changed Callback," + (LocationError)ret);
666 throw LocationErrorFactory.ThrowLocationException(ret);
671 /// The ZoneChanged event is invoked when the previously set boundary area is entered or left.
673 /// <since_tizen> 3 </since_tizen>
674 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
675 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
676 public event EventHandler<ZoneChangedEventArgs> ZoneChanged
680 Log.Info(Globals.LogTag, "ZoneChanged called");
681 if (_zoneChanged == null)
683 Log.Info(Globals.LogTag, "Calling function SetZoneChangedCallback");
684 SetZoneChangedCallback();
686 _zoneChanged += value;
690 Log.Info(Globals.LogTag, "Callback removed");
691 _zoneChanged -= value;
693 if (_zoneChanged == null)
695 Log.Info(Globals.LogTag, "Calling function UnSetZoneChangedCallback");
696 UnSetZoneChangedCallback();
701 private void SetZoneChangedCallback()
703 Log.Info(Globals.LogTag, "Inside SetZoneChangedCallback");
704 if (_zoneChangedCallback == null)
706 _zoneChangedCallback = (state, latitude, longitude, altitude, timestamp, userData) =>
708 Log.Info(Globals.LogTag, "Inside ZoneChangedCallback");
709 DateTime timeStamp = DateTime.Now;
712 DateTime start = DateTime.SpecifyKind(new DateTime(1970, 1, 1).AddSeconds(timestamp), DateTimeKind.Utc);
713 timeStamp = start.ToLocalTime();
715 _zoneChanged?.Invoke(this, new ZoneChangedEventArgs(state, latitude, longitude, altitude, timeStamp));
719 int ret = Interop.LocatorEvent.SetZoneChangedCallback(_handle, _zoneChangedCallback, IntPtr.Zero);
720 if (((LocationError)ret != LocationError.None))
722 Log.Error(Globals.LogTag, "Error in Setting Zone Changed Callback," + (LocationError)ret);
723 throw LocationErrorFactory.ThrowLocationException(ret);
727 private void UnSetZoneChangedCallback()
729 Log.Info(Globals.LogTag, "Inside UnSetZoneChangedCallback");
730 int ret = Interop.LocatorEvent.UnSetZoneChangedCallback(_handle);
731 if (((LocationError)ret != LocationError.None))
733 Log.Error(Globals.LogTag, "Error in UnSetting Zone Changed Callback," + (LocationError)ret);
738 /// The SetttingChanged event is raised when the location setting is changed.
740 /// <since_tizen> 3 </since_tizen>
741 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
742 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
743 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
744 public event EventHandler<SettingChangedEventArgs> SettingChanged
748 Log.Info(Globals.LogTag, "Adding SettingChanged EventHandler");
749 if (_settingChanged == null)
751 Log.Info(Globals.LogTag, "Calling function SetSettingChangedCallback");
752 SetSettingChangedCallback();
754 _settingChanged += value;
758 Log.Info(Globals.LogTag, "Removing SettingChanged EventHandler");
759 _settingChanged -= value;
761 if (_settingChanged == null)
763 Log.Info(Globals.LogTag, "Calling function UnSetSettingChangedCallback");
764 UnSetSettingChangedCallback();
769 private void SetSettingChangedCallback()
771 Log.Info(Globals.LogTag, "Calling SetSettingChangedCallback");
772 if (_settingChangedCallback == null)
774 _settingChangedCallback = (method, enable, userData) =>
776 Log.Info(Globals.LogTag, "Calling SettingChangedCallback");
777 _settingChanged?.Invoke(this, new SettingChangedEventArgs(method, enable));
781 int ret = Interop.LocatorEvent.SetSettingChangedCallback((int)_locationType, _settingChangedCallback, IntPtr.Zero);
782 if (((LocationError)ret != LocationError.None))
784 Log.Error(Globals.LogTag, "Error in Setting Changed Callback," + (LocationError)ret);
785 throw LocationErrorFactory.ThrowLocationException(ret);
789 private void UnSetSettingChangedCallback()
791 Log.Info(Globals.LogTag, "Calling UnSetSettingChangedCallback");
792 int ret = Interop.LocatorEvent.UnSetSettingChangedCallback((int)_locationType);
793 if (((LocationError)ret != LocationError.None))
795 Log.Error(Globals.LogTag, "Error in Unsetting Setting's Callback," + (LocationError)ret);
796 throw LocationErrorFactory.ThrowLocationException(ret);
801 /// The DistanceBasedLocationChanged event is raised with the updated location information.
802 /// The callback will be invoked at a minimum interval or minimum distance with the updated position information.
804 /// <since_tizen> 3 </since_tizen>
805 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
806 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
807 public event EventHandler<LocationChangedEventArgs> DistanceBasedLocationChanged
811 Log.Info(Globals.LogTag, "Adding DistanceBasedLocationChanged EventHandler");
812 //if (_distanceBasedLocationChanged == null)
814 Log.Info(Globals.LogTag, "Calling function SetDistanceBasedLocationChangedCallback");
815 SetDistanceBasedLocationChangedCallback();
817 _distanceBasedLocationChanged += value;
821 Log.Info(Globals.LogTag, "Removing DistanceBasedLocationChanged EventHandler");
822 _distanceBasedLocationChanged -= value;
824 if (_distanceBasedLocationChanged == null)
826 Log.Info(Globals.LogTag, "Calling function UnSetDistanceBasedLocationChangedCallback");
827 UnSetDistanceBasedLocationChangedCallback();
832 private void SetDistanceBasedLocationChangedCallback()
834 Log.Info(Globals.LogTag, "SetDistanceBasedLocationChangedCallback");
835 if (_distanceBasedLocationChangedCallback == null) {
836 _distanceBasedLocationChangedCallback = (latitude, longitude, altitude, speed, direction, accuracy, timestamp, userData) =>
838 Log.Info(Globals.LogTag, "DistanceBasedLocationChangedCallback #1");
839 Location location = new Location(latitude, longitude, altitude, speed, direction, accuracy, timestamp);
840 Log.Info(Globals.LogTag, "DistanceBasedLocationChangedCallback #2");
841 _distanceBasedLocationChanged?.Invoke(this, new LocationChangedEventArgs(location));
842 Log.Info(Globals.LogTag, "DistanceBasedLocationChangedCallback #3");
846 int ret = Interop.LocatorEvent.SetDistanceBasedLocationChangedCallback(_handle, _distanceBasedLocationChangedCallback, _stayInterval, _distance, IntPtr.Zero);
847 if (((LocationError)ret != LocationError.None))
849 Log.Error(Globals.LogTag, "Error in Setting Distance based location changed Callback," + (LocationError)ret);
850 throw LocationErrorFactory.ThrowLocationException(ret);
854 private void UnSetDistanceBasedLocationChangedCallback()
856 Log.Info(Globals.LogTag, "UnSetDistanceBasedLocationChangedCallback");
857 int ret = Interop.LocatorEvent.UnSetDistanceBasedLocationChangedCallback(_handle);
858 if (((LocationError)ret != LocationError.None))
860 Log.Error(Globals.LogTag, "Error in UnSetting Distance based location changed Callback," + (LocationError)ret);
861 throw LocationErrorFactory.ThrowLocationException(ret);
863 _distanceBasedLocationChanged = null;
867 /// The LocationUpdated event is raised at defined intervals of time with the updated location information.
868 /// The callback will be invoked periodically.
870 /// <since_tizen> 3 </since_tizen>
871 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
872 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
873 public event EventHandler<LocationChangedEventArgs> LocationChanged
877 Log.Info(Globals.LogTag, "Adding LocationChanged EventHandler");
878 if (_batchPeriod > 0 && _batchPeriod > _batchInterval)
880 Log.Info(Globals.LogTag, "Calling function SetLocationBatchCallback");
881 SetLocationBatchCallback();
885 Log.Info(Globals.LogTag, "Calling function SetLocationChangedCallback");
886 SetLocationChangedCallback();
888 _locationChanged += value;
892 Log.Info(Globals.LogTag, "Removing LocationChanged EventHandler");
893 _locationChanged -= value;
895 if (_locationChanged == null)
897 if (_batchPeriod > 0 && _batchPeriod > _batchInterval)
899 Log.Info(Globals.LogTag, "Calling function UnSetLocationBatchCallback");
900 UnSetLocationBatchCallback();
904 Log.Info(Globals.LogTag, "Calling function UnSetLocationChangedCallback");
905 UnSetLocationChangedCallback();
911 private void SetLocationChangedCallback()
913 Log.Info(Globals.LogTag, "Calling SetLocationChangedCallback");
915 if (_locationChangedCallback == null) {
916 _locationChangedCallback = (latitude, longitude, altitude, speed, direction, accuracy, timestamp, userData) =>
918 Log.Info(Globals.LogTag, "LocationChangedCallback has been called");
919 Location location = new Location(latitude, longitude, altitude, speed, direction, accuracy, timestamp);
920 _location = location;
921 _locationChanged?.Invoke(this, new LocationChangedEventArgs(location));
925 int ret = Interop.LocatorEvent.SetLocationChangedCallback(_handle, _locationChangedCallback, _interval, IntPtr.Zero);
926 if (((LocationError)ret != LocationError.None))
928 Log.Error(Globals.LogTag, "Error in Setting location changed Callback," + (LocationError)ret);
929 throw LocationErrorFactory.ThrowLocationException(ret);
933 private void UnSetLocationChangedCallback()
935 Log.Info(Globals.LogTag, "Calling UnSetLocationChangedCallback");
936 int ret = Interop.LocatorEvent.UnSetLocationChangedCallback(_handle);
937 if (((LocationError)ret != LocationError.None))
939 Log.Error(Globals.LogTag, "Error in UnSetting location changed Callback," + (LocationError)ret);
940 throw LocationErrorFactory.ThrowLocationException(ret);
944 private void SetLocationBatchCallback()
946 Log.Info(Globals.LogTag, "Calling SetLocationBatchCallback");
948 if (_locationBatchCallback == null) {
949 _locationBatchCallback = (batch_size, userData) =>
951 Log.Info(Globals.LogTag, "LocationBatchCallback has been called, size : " + batch_size);
953 _locationBatchGetCallback = (latitude, longitude, altitude, speed, direction, horizontal, vertical, timestamp, batchUserData) =>
955 Log.Info(Globals.LogTag, "GetLocationBatch has been called");
956 Location location = new Location(latitude, longitude, altitude, speed, direction, horizontal, timestamp);
957 _location = location;
958 _locationChanged?.Invoke(this, new LocationChangedEventArgs(location));
961 ret = Interop.LocatorEvent.GetLocationBatch(_handle, _locationBatchGetCallback, IntPtr.Zero);
962 if (((LocationError)ret != LocationError.None))
964 Log.Error(Globals.LogTag, "Error in Setting location batch Callback," + (LocationError)ret);
965 throw LocationErrorFactory.ThrowLocationException(ret);
970 ret = Interop.LocatorEvent.SetLocationBatchCallback(_handle, _locationBatchCallback, _batchInterval, _batchPeriod, IntPtr.Zero);
971 if (((LocationError)ret != LocationError.None))
973 Log.Error(Globals.LogTag, "Error in Setting location batch Callback," + (LocationError)ret);
974 throw LocationErrorFactory.ThrowLocationException(ret);
978 private void UnSetLocationBatchCallback()
980 Log.Info(Globals.LogTag, "Calling UnSetLocationBatchCallback");
981 int ret = Interop.LocatorEvent.UnSetLocationBatchCallback(_handle);
982 if (((LocationError)ret != LocationError.None))
984 Log.Error(Globals.LogTag, "Error in UnSetting location batch Callback," + (LocationError)ret);
985 throw LocationErrorFactory.ThrowLocationException(ret);