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 infomation 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 _isStarted = false;
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</feature>
72 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
73 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
74 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
75 public Locator(LocationType locationType)
77 Log.Info(Globals.LogTag, "Locator Constructor");
78 int ret = Interop.Locator.Create((int)locationType, out _handle);
79 if (((LocationError)ret != LocationError.None))
81 Log.Error(Globals.LogTag, "Error creating Location Manager," + (LocationError)ret);
82 throw LocationErrorFactory.ThrowLocationException(ret);
84 _location = new Location();
85 _locationType = locationType;
89 /// The destructor of the Locator class.
91 /// <since_tizen> 3 </since_tizen>
98 /// The time interval between callback updates.
99 /// Should be in the range of 1~120 seconds.
101 /// <since_tizen> 3 </since_tizen>
102 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
107 Log.Info(Globals.LogTag, "Getting the Callback Interval");
112 Log.Info(Globals.LogTag, "Setting the Callback Interval");
113 if (value > 0 && value <= 120)
119 Log.Error(Globals.LogTag, "Error setting Callback Interval");
120 throw LocationErrorFactory.ThrowLocationException((int)LocationError.InvalidParameter);
126 /// The time interval between the distance-based location callback updates.
127 /// Should be in the range of 1~120 seconds.
129 /// <since_tizen> 3 </since_tizen>
130 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
131 public int StayInterval
135 Log.Info(Globals.LogTag, "Getting the StayInterval");
136 return _stayInterval;
140 Log.Info(Globals.LogTag, "Setting the StayInterval");
141 if (value > 0 && value <= 120)
143 _stayInterval = value;
147 Log.Error(Globals.LogTag, "Error Setting the StayInterval");
148 throw LocationErrorFactory.ThrowLocationException((int)LocationError.InvalidParameter);
154 /// The time interval between the position collection in batch mode.
155 /// Should be in the range of 1~255 seconds.
157 /// <since_tizen> 3 </since_tizen>
158 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
159 public int BatchInterval
163 Log.Info(Globals.LogTag, "Getting the Batch Interval");
164 return _batchInterval;
168 Log.Info(Globals.LogTag, "Setting the Batch Interval");
169 if (value > 0 && value <= 255)
171 _batchInterval = value;
175 Log.Error(Globals.LogTag, "Error setting Callback Interval");
176 throw LocationErrorFactory.ThrowLocationException((int)LocationError.InvalidParameter);
182 /// 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.
183 /// Should be in the range of 0~60000 seconds.
185 /// <since_tizen> 3 </since_tizen>
186 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
187 public int BatchPeriod
191 Log.Info(Globals.LogTag, "Getting the Batch Period");
196 Log.Info(Globals.LogTag, "Setting the Batch Period");
197 if (value >= 0 && value <= 60000)
199 _batchPeriod = value;
203 Log.Error(Globals.LogTag, "Error setting Batch Period");
204 throw LocationErrorFactory.ThrowLocationException((int)LocationError.InvalidParameter);
210 /// The distance between callback updates.
211 /// Should be in the range of 1-120 meters.
213 /// <since_tizen> 3 </since_tizen>
214 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
215 public double Distance
219 Log.Info(Globals.LogTag, "Getting the Distance Interval");
224 Log.Info(Globals.LogTag, "Setting the Distance Interval");
225 if (value > 0 && value <= 120)
231 Log.Error(Globals.LogTag, "Error Setting the Distance");
232 throw LocationErrorFactory.ThrowLocationException((int)LocationError.InvalidParameter);
238 /// Gets the location object.
240 /// <since_tizen> 3 </since_tizen>
241 public Location Location
245 Log.Info(Globals.LogTag, "Getting location details");
251 /// Gets the type used to obtain the location data.
253 /// <since_tizen> 3 </since_tizen>
254 public LocationType LocationType
258 Log.Info(Globals.LogTag, "Getting LocationType");
259 return _locationType;
264 /// Gets the status whether the mock location is enabled or not.
266 /// <since_tizen> 3 </since_tizen>
267 /// <privilege>http://tizen.org/privilege/location</privilege>
268 /// <exception cref="UnauthroizedAccessException">Thrown when the application has no privilege to use the location.</exception>
269 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
270 public bool EnableMock
274 Log.Info(Globals.LogTag, "Getting getting Mock");
275 _isEnableMock = GetEnableMock();
276 return _isEnableMock;
280 _isEnableMock = value;
285 internal IntPtr GetHandle()
290 private bool GetEnableMock()
293 int ret = Interop.Locator.IsEnabledMock(out status);
294 if (((LocationError)ret != LocationError.None))
296 Log.Error(Globals.LogTag, "Error Get Enable Mock Status," + (LocationError)ret);
297 throw LocationErrorFactory.ThrowLocationException(ret);
302 private void SetEnableMock()
304 int ret = Interop.Locator.EnableMock(_isEnableMock);
305 if (((LocationError)ret != LocationError.None))
307 Log.Error(Globals.LogTag, "Error Set Enable Mock Status," + (LocationError)ret);
308 throw LocationErrorFactory.ThrowLocationException(ret);
313 /// Starts the Location Manager which has been created using the specified method.
315 /// <since_tizen> 3 </since_tizen>
316 /// <privilege>http://tizen.org/privilege/location</privilege>
317 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
318 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
319 /// <exception cref="UnauthroizedAccessException">Thrown when the application has no privilege to use the location.</exception>
320 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
323 Log.Info(Globals.LogTag, "Starting Location Manager");
324 if (_batchPeriod > 0 && _batchPeriod > _batchInterval)
326 int ret = Interop.Locator.StartBatch(_handle);
327 if (((LocationError)ret != LocationError.None))
329 Log.Error(Globals.LogTag, "Error Starting Location Batch mode," + (LocationError)ret);
330 throw LocationErrorFactory.ThrowLocationException(ret);
335 int ret = Interop.Locator.Start(_handle);
336 if (((LocationError)ret != LocationError.None))
338 Log.Error(Globals.LogTag, "Error Starting Location Manager," + (LocationError)ret);
339 throw LocationErrorFactory.ThrowLocationException(ret);
346 /// Stops the Location Manager which has been activated using the specified method.
347 /// Does not destroy the manager.
349 /// <since_tizen> 3 </since_tizen>
350 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
351 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
352 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
355 Log.Info(Globals.LogTag, "Stopping Location Manager");
356 int ret = Interop.Locator.Stop(_handle);
357 if (((LocationError)ret != LocationError.None))
359 Log.Error(Globals.LogTag, "Error stopping Location Manager," + (LocationError)ret);
360 throw LocationErrorFactory.ThrowLocationException(ret);
366 /// Sets a mock location for the given location method.
368 /// <since_tizen> 3 </since_tizen>
369 /// <param name="location"> The location object containing the mock location details.</param>
370 /// <privilege>http://tizen.org/privilege/location</privilege>
371 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
372 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
373 /// <exception cref="UnauthroizedAccessException">Thrown when the application has no privilege to use the location.</exception>
374 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
375 public void SetMockLocation(Location location)
377 Log.Info(Globals.LogTag, "Setting mock location");
378 int ret = Interop.Locator.SetMockLocation(_handle, location.Latitude, location.Longitude, location.Altitude, location.Speed, location.Direction, location.Accuracy);
379 if (((LocationError)ret == LocationError.None))
381 _location.Latitude = location.Latitude;
382 _location.Longitude = location.Longitude;
383 _location.Altitude = location.Altitude;
384 _location.Speed = location.Speed;
385 _location.Direction = location.Direction;
386 _location.Accuracy = location.Accuracy;
390 Log.Error(Globals.LogTag, "Error in setting up location mocking," + (LocationError)ret);
391 throw LocationErrorFactory.ThrowLocationException(ret);
396 /// Clears a mock location for the given location method.
398 /// <since_tizen> 3 </since_tizen>
399 /// <privilege>http://tizen.org/privilege/location</privilege>
400 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
401 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
402 /// <exception cref="UnauthroizedAccessException">Thrown when the application has no privilege to use the location.</exception>
403 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
404 public void ClearMock()
406 Log.Info(Globals.LogTag, "Clear mock location");
407 int ret = Interop.Locator.ClearMock(_handle);
408 if (((LocationError)ret != LocationError.None))
410 Log.Error(Globals.LogTag, "Error in clear up location mocking," + (LocationError)ret);
411 throw LocationErrorFactory.ThrowLocationException(ret);
416 /// Gets the details of the location asynchronously.
418 /// <since_tizen> 3 </since_tizen>
419 /// <param name="timeout"> Timeout to stop requesting a single location after (seconds).</param>
420 /// <returns> A task which contains the current location details.</returns>
421 /// <privilege>http://tizen.org/privilege/location</privilege>
422 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
423 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
424 /// <exception cref="UnauthroizedAccessException">Thrown when the application has no privilege to use the location.</exception>
425 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
426 public Task<Location> GetLocationAsync(int timeout)
428 var task = new TaskCompletionSource<Location>();
429 IntPtr id = IntPtr.Zero;
432 id = (IntPtr)_requestId++;
433 _callback_map[id] = (LocationError error, double latitude, double longitude, double altitude, int timestamp, double speed, double direction, double climb, IntPtr userData) =>
435 if (error != LocationError.None)
437 Log.Error(Globals.LogTag, "Error in getting up location information," + (LocationError)error);
441 Log.Info(Globals.LogTag, "Creating a current location object");
442 _location = new Location(latitude, longitude, altitude, speed, direction, 0.0, timestamp);
443 task.SetResult(_location);
447 _callback_map.Remove(userData);
452 int ret = Interop.LocatorEvent.GetSingleLocation(_handle, timeout, _callback_map[id], id);
453 if (((LocationError)ret != LocationError.None))
455 Log.Error(Globals.LogTag, "Error in setting up location mocking," + (LocationError)ret);
456 throw LocationErrorFactory.ThrowLocationException(ret);
463 /// Gets the details of the location.
465 /// <since_tizen> 3 </since_tizen>
466 /// <returns> Which contains the current location details.</returns>
467 /// <privilege>http://tizen.org/privilege/location</privilege>
468 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
469 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
470 /// <exception cref="UnauthroizedAccessException">Thrown when the application has no privilege to use the location.</exception>
471 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
472 public Location GetLocation()
475 double longitude = 0;
479 double direction = 0;
487 Log.Info(Globals.LogTag, "Get current location information");
488 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);
489 if (((LocationError)ret != LocationError.None))
491 Log.Error(Globals.LogTag, "Error in get current location infomation," + (LocationError)ret);
492 throw LocationErrorFactory.ThrowLocationException(ret);
497 Log.Info(Globals.LogTag, "Get last location information");
498 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);
499 if (((LocationError)ret != LocationError.None))
501 Log.Error(Globals.LogTag, "Error in get last location information," + (LocationError)ret);
502 throw LocationErrorFactory.ThrowLocationException(ret);
506 Location location = new Location(latitude, longitude, altitude, speed, direction, accuracy, timestamp);
507 _location = location;
514 /// Adds a bound for a given locator.
516 /// <since_tizen> 3 </since_tizen>
517 /// <param name="locationBoundary">The boundary object to be added to the locator.</param>
518 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
519 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
520 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
521 public void AddBoundary(LocationBoundary locationBoundary)
523 Log.Info(Globals.LogTag, "AddBoundary called");
525 int ret = Interop.Locator.AddBoundary(_handle, locationBoundary.GetHandle());
526 if ((LocationBoundError)ret != LocationBoundError.None)
528 Log.Error(Globals.LogTag, "Error Adding Boundary," + (LocationBoundError)ret);
529 throw LocationErrorFactory.ThrowLocationBoundaryException(ret);
534 /// Deletes a bound for a given locator.
536 /// <since_tizen> 3 </since_tizen>
537 /// <param name="locationBoundary"> The boundary object to be removed from 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 RemoveBoundary(LocationBoundary locationBoundary)
543 Log.Info(Globals.LogTag, "RemoveBoundary called");
544 int ret = Interop.Locator.RemoveBoundary(_handle, locationBoundary.GetHandle());
545 if ((LocationBoundError)ret != LocationBoundError.None)
547 Log.Error(Globals.LogTag, "Error Removing Boundary," + (LocationBoundError)ret);
548 throw LocationErrorFactory.ThrowLocationBoundaryException(ret);
553 /// The overidden Dispose method of the IDisposable class.
555 /// <since_tizen> 3 </since_tizen>
556 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
557 public void Dispose()
560 GC.SuppressFinalize(this);
563 protected virtual void Dispose(bool disposing)
574 private void DestroyHandle()
576 int ret = Interop.Locator.Destroy(_handle);
577 if (((LocationError)ret != LocationError.None))
579 Log.Error(Globals.LogTag, "Error in Destroy handle, " + (LocationError)ret);
580 throw LocationErrorFactory.ThrowLocationException(ret);
585 /// The ServiceStateChanged event is invoked when the location service state is changed.
587 /// <since_tizen> 3 </since_tizen>
588 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
589 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
590 public event EventHandler<ServiceStateChangedEventArgs> ServiceStateChanged
594 Log.Info(Globals.LogTag, "ServiceStateChanged called");
595 if (_serviceStateChanged == null)
597 Log.Info(Globals.LogTag, "Calling function SetServiceStateChangedCallback");
598 SetServiceStateChangedCallback();
600 _serviceStateChanged += value;
604 Log.Info(Globals.LogTag, "Callback removed");
605 _serviceStateChanged -= value;
607 if (_serviceStateChanged == null)
609 Log.Info(Globals.LogTag, "Calling function UnSetServiceStateChangedCallback");
610 UnSetServiceStateChangedCallback();
615 private void SetServiceStateChangedCallback()
617 Log.Info(Globals.LogTag, "Calling Interop.LocatorEvent.SetServiceStateChangedCallback");
618 if (_serviceStateChangedCallback == null)
620 _serviceStateChangedCallback = (state, userData) =>
622 Log.Info(Globals.LogTag, "Inside ServiceStateChangedCallback");
623 _serviceStateChanged?.Invoke(this, new ServiceStateChangedEventArgs(state));
627 int ret = Interop.LocatorEvent.SetServiceStateChangedCallback(_handle, _serviceStateChangedCallback, IntPtr.Zero);
628 if (((LocationError)ret != LocationError.None))
630 Log.Error(Globals.LogTag, "Error in Setting Service State Changed Callback," + (LocationError)ret);
631 throw LocationErrorFactory.ThrowLocationException(ret);
635 private void UnSetServiceStateChangedCallback()
637 Log.Info(Globals.LogTag, "Calling Interop.LocatorEvent.UnSetServiceStateChangedCallback");
638 int ret = Interop.LocatorEvent.UnSetServiceStateChangedCallback(_handle);
639 if (((LocationError)ret != LocationError.None))
641 Log.Error(Globals.LogTag, "Error in UnSetting Service State Changed Callback," + (LocationError)ret);
642 throw LocationErrorFactory.ThrowLocationException(ret);
647 /// The ZoneChanged event is invoked when the previously set boundary area is entered or left.
649 /// <since_tizen> 3 </since_tizen>
650 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
651 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
652 public event EventHandler<ZoneChangedEventArgs> ZoneChanged
656 Log.Info(Globals.LogTag, "ZoneChanged called");
657 if (_zoneChanged == null)
659 Log.Info(Globals.LogTag, "Calling function SetZoneChangedCallback");
660 SetZoneChangedCallback();
662 _zoneChanged += value;
666 Log.Info(Globals.LogTag, "Callback removed");
667 _zoneChanged -= value;
669 if (_zoneChanged == null)
671 Log.Info(Globals.LogTag, "Calling function UnSetZoneChangedCallback");
672 UnSetZoneChangedCallback();
677 private void SetZoneChangedCallback()
679 Log.Info(Globals.LogTag, "Inside SetZoneChangedCallback");
680 if (_zoneChangedCallback == null)
682 _zoneChangedCallback = (state, latitude, longitude, altitude, timestamp, userData) =>
684 Log.Info(Globals.LogTag, "Inside ZoneChangedCallback");
685 DateTime timeStamp = DateTime.Now;
688 DateTime start = DateTime.SpecifyKind(new DateTime(1970, 1, 1).AddSeconds(timestamp), DateTimeKind.Utc);
689 timeStamp = start.ToLocalTime();
691 _zoneChanged?.Invoke(this, new ZoneChangedEventArgs(state, latitude, longitude, altitude, timeStamp));
695 int ret = Interop.LocatorEvent.SetZoneChangedCallback(_handle, _zoneChangedCallback, IntPtr.Zero);
696 if (((LocationError)ret != LocationError.None))
698 Log.Error(Globals.LogTag, "Error in Setting Zone Changed Callback," + (LocationError)ret);
699 throw LocationErrorFactory.ThrowLocationException(ret);
703 private void UnSetZoneChangedCallback()
705 Log.Info(Globals.LogTag, "Inside UnSetZoneChangedCallback");
706 int ret = Interop.LocatorEvent.UnSetZoneChangedCallback(_handle);
707 if (((LocationError)ret != LocationError.None))
709 Log.Error(Globals.LogTag, "Error in UnSetting Zone Changed Callback," + (LocationError)ret);
714 /// The SetttingChanged event is raised when the location setting is changed.
716 /// <since_tizen> 3 </since_tizen>
717 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
718 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
719 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
720 public event EventHandler<SettingChangedEventArgs> SettingChanged
724 Log.Info(Globals.LogTag, "Adding SettingChanged EventHandler");
725 if (_settingChanged == null)
727 Log.Info(Globals.LogTag, "Calling function SetSettingChangedCallback");
728 SetSettingChangedCallback();
730 _settingChanged += value;
734 Log.Info(Globals.LogTag, "Removing SettingChanged EventHandler");
735 _settingChanged -= value;
737 if (_settingChanged == null)
739 Log.Info(Globals.LogTag, "Calling function UnSetSettingChangedCallback");
740 UnSetSettingChangedCallback();
745 private void SetSettingChangedCallback()
747 Log.Info(Globals.LogTag, "Calling SetSettingChangedCallback");
748 if (_settingChangedCallback == null)
750 _settingChangedCallback = (method, enable, userData) =>
752 Log.Info(Globals.LogTag, "Calling SettingChangedCallback");
753 _settingChanged?.Invoke(this, new SettingChangedEventArgs(method, enable));
757 int ret = Interop.LocatorEvent.SetSettingChangedCallback((int)_locationType, _settingChangedCallback, IntPtr.Zero);
758 if (((LocationError)ret != LocationError.None))
760 Log.Error(Globals.LogTag, "Error in Setting Changed Callback," + (LocationError)ret);
761 throw LocationErrorFactory.ThrowLocationException(ret);
765 private void UnSetSettingChangedCallback()
767 Log.Info(Globals.LogTag, "Calling UnSetSettingChangedCallback");
768 int ret = Interop.LocatorEvent.UnSetSettingChangedCallback((int)_locationType);
769 if (((LocationError)ret != LocationError.None))
771 Log.Error(Globals.LogTag, "Error in Unsetting Setting's Callback," + (LocationError)ret);
772 throw LocationErrorFactory.ThrowLocationException(ret);
777 /// The DistanceBasedLocationChanged event is raised with the updated location information.
778 /// The callback will be invoked at a minimum interval or minimum distance with the updated position information.
780 /// <since_tizen> 3 </since_tizen>
781 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
782 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
783 public event EventHandler<LocationChangedEventArgs> DistanceBasedLocationChanged
787 Log.Info(Globals.LogTag, "Adding DistanceBasedLocationChanged EventHandler");
788 //if (_distanceBasedLocationChanged == null)
790 Log.Info(Globals.LogTag, "Calling function SetDistanceBasedLocationChangedCallback");
791 SetDistanceBasedLocationChangedCallback();
793 _distanceBasedLocationChanged += value;
797 Log.Info(Globals.LogTag, "Removing DistanceBasedLocationChanged EventHandler");
798 _distanceBasedLocationChanged -= value;
800 if (_distanceBasedLocationChanged == null)
802 Log.Info(Globals.LogTag, "Calling function UnSetDistanceBasedLocationChangedCallback");
803 UnSetDistanceBasedLocationChangedCallback();
808 private void SetDistanceBasedLocationChangedCallback()
810 Log.Info(Globals.LogTag, "SetDistanceBasedLocationChangedCallback");
811 if (_distanceBasedLocationChangedCallback == null) {
812 _distanceBasedLocationChangedCallback = (latitude, longitude, altitude, speed, direction, accuracy, timestamp, userData) =>
814 Log.Info(Globals.LogTag, "DistanceBasedLocationChangedCallback #1");
815 Location location = new Location(latitude, longitude, altitude, speed, direction, accuracy, timestamp);
816 Log.Info(Globals.LogTag, "DistanceBasedLocationChangedCallback #2");
817 _distanceBasedLocationChanged?.Invoke(this, new LocationChangedEventArgs(location));
818 Log.Info(Globals.LogTag, "DistanceBasedLocationChangedCallback #3");
822 int ret = Interop.LocatorEvent.SetDistanceBasedLocationChangedCallback(_handle, _distanceBasedLocationChangedCallback, _stayInterval, _distance, IntPtr.Zero);
823 if (((LocationError)ret != LocationError.None))
825 Log.Error(Globals.LogTag, "Error in Setting Distance based location changed Callback," + (LocationError)ret);
826 throw LocationErrorFactory.ThrowLocationException(ret);
830 private void UnSetDistanceBasedLocationChangedCallback()
832 Log.Info(Globals.LogTag, "UnSetDistanceBasedLocationChangedCallback");
833 int ret = Interop.LocatorEvent.UnSetDistanceBasedLocationChangedCallback(_handle);
834 if (((LocationError)ret != LocationError.None))
836 Log.Error(Globals.LogTag, "Error in UnSetting Distance based location changed Callback," + (LocationError)ret);
837 throw LocationErrorFactory.ThrowLocationException(ret);
839 _distanceBasedLocationChanged = null;
843 /// The LocationUpdated event is raised at defined intervals of time with the updated location information.
844 /// The callback will be invoked periodically.
846 /// <since_tizen> 3 </since_tizen>
847 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
848 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
849 public event EventHandler<LocationChangedEventArgs> LocationChanged
853 Log.Info(Globals.LogTag, "Adding LocationChanged EventHandler");
854 if (_batchPeriod > 0 && _batchPeriod > _batchInterval)
856 Log.Info(Globals.LogTag, "Calling function SetLocationBatchCallback");
857 SetLocationBatchCallback();
861 Log.Info(Globals.LogTag, "Calling function SetLocationChangedCallback");
862 SetLocationChangedCallback();
864 _locationChanged += value;
868 Log.Info(Globals.LogTag, "Removing LocationChanged EventHandler");
869 _locationChanged -= value;
871 if (_locationChanged == null)
873 if (_batchPeriod > 0 && _batchPeriod > _batchInterval)
875 Log.Info(Globals.LogTag, "Calling function UnSetLocationBatchCallback");
876 UnSetLocationBatchCallback();
880 Log.Info(Globals.LogTag, "Calling function UnSetLocationChangedCallback");
881 UnSetLocationChangedCallback();
887 private void SetLocationChangedCallback()
889 Log.Info(Globals.LogTag, "Calling SetLocationChangedCallback");
891 if (_locationChangedCallback == null) {
892 _locationChangedCallback = (latitude, longitude, altitude, speed, direction, accuracy, timestamp, userData) =>
894 Log.Info(Globals.LogTag, "LocationChangedCallback has been called");
895 Location location = new Location(latitude, longitude, altitude, speed, direction, accuracy, timestamp);
896 _location = location;
897 _locationChanged?.Invoke(this, new LocationChangedEventArgs(location));
901 int ret = Interop.LocatorEvent.SetLocationChangedCallback(_handle, _locationChangedCallback, _interval, IntPtr.Zero);
902 if (((LocationError)ret != LocationError.None))
904 Log.Error(Globals.LogTag, "Error in Setting location changed Callback," + (LocationError)ret);
905 throw LocationErrorFactory.ThrowLocationException(ret);
909 private void UnSetLocationChangedCallback()
911 Log.Info(Globals.LogTag, "Calling UnSetLocationChangedCallback");
912 int ret = Interop.LocatorEvent.UnSetLocationChangedCallback(_handle);
913 if (((LocationError)ret != LocationError.None))
915 Log.Error(Globals.LogTag, "Error in UnSetting location changed Callback," + (LocationError)ret);
916 throw LocationErrorFactory.ThrowLocationException(ret);
920 private void SetLocationBatchCallback()
922 Log.Info(Globals.LogTag, "Calling SetLocationBatchCallback");
924 if (_locationBatchCallback == null) {
925 _locationBatchCallback = (batch_size, userData) =>
927 Log.Info(Globals.LogTag, "LocationBatchCallback has been called, size : " + batch_size);
929 _locationBatchGetCallback = (latitude, longitude, altitude, speed, direction, horizontal, vertical, timestamp, batchUserData) =>
931 Log.Info(Globals.LogTag, "GetLocationBatch has been called");
932 Location location = new Location(latitude, longitude, altitude, speed, direction, horizontal, timestamp);
933 _location = location;
934 _locationChanged?.Invoke(this, new LocationChangedEventArgs(location));
937 ret = Interop.LocatorEvent.GetLocationBatch(_handle, _locationBatchGetCallback, IntPtr.Zero);
938 if (((LocationError)ret != LocationError.None))
940 Log.Error(Globals.LogTag, "Error in Setting location batch Callback," + (LocationError)ret);
941 throw LocationErrorFactory.ThrowLocationException(ret);
946 ret = Interop.LocatorEvent.SetLocationBatchCallback(_handle, _locationBatchCallback, _batchInterval, _batchPeriod, IntPtr.Zero);
947 if (((LocationError)ret != LocationError.None))
949 Log.Error(Globals.LogTag, "Error in Setting location batch Callback," + (LocationError)ret);
950 throw LocationErrorFactory.ThrowLocationException(ret);
954 private void UnSetLocationBatchCallback()
956 Log.Info(Globals.LogTag, "Calling UnSetLocationBatchCallback");
957 int ret = Interop.LocatorEvent.UnSetLocationBatchCallback(_handle);
958 if (((LocationError)ret != LocationError.None))
960 Log.Error(Globals.LogTag, "Error in UnSetting location batch Callback," + (LocationError)ret);
961 throw LocationErrorFactory.ThrowLocationException(ret);