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 /// <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 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 Locator class.
91 /// <since_tizen>3</since_tizen>
98 /// The time interval between callback updates.
99 /// Should be in the range [1~120] seconds.
101 /// <since_tizen>3</since_tizen>
102 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
103 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</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 Distance based location callback updates.
128 /// Should be in the range [1~120] seconds.
130 /// <since_tizen>3</since_tizen>
131 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
132 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
133 public int StayInterval
137 Log.Info(Globals.LogTag, "Getting the StayInterval");
138 return _stayInterval;
142 Log.Info(Globals.LogTag, "Setting the StayInterval");
143 if (value > 0 && value <= 120)
145 _stayInterval = value;
149 Log.Error(Globals.LogTag, "Error Setting the StayInterval");
150 throw LocationErrorFactory.ThrowLocationException((int)LocationError.InvalidParameter);
156 /// The time interval between position collection in batch mode.
157 /// Should be in the range [1~255] seconds.
159 /// <since_tizen>3</since_tizen>
160 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
161 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
162 public int BatchInterval
166 Log.Info(Globals.LogTag, "Getting the Batch Interval");
167 return _batchInterval;
171 Log.Info(Globals.LogTag, "Setting the Batch Interval");
172 if (value > 0 && value <= 255)
174 _batchInterval = value;
178 Log.Error(Globals.LogTag, "Error setting Callback Interval");
179 throw LocationErrorFactory.ThrowLocationException((int)LocationError.InvalidParameter);
185 /// The time interval between batch callback updates. The BatchPeriod should be greater than or equal to the BatchInterval. If BatchPeriod is zero or smaller than BatchInterval, then batch mode will not working.
186 /// Should be in the range [0~60000] seconds.
188 /// <since_tizen>3</since_tizen>
189 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
190 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
191 public int BatchPeriod
195 Log.Info(Globals.LogTag, "Getting the Batch Period");
200 Log.Info(Globals.LogTag, "Setting the Batch Period");
201 if (value >= 0 && value <= 60000)
203 _batchPeriod = value;
207 Log.Error(Globals.LogTag, "Error setting Batch Period");
208 throw LocationErrorFactory.ThrowLocationException((int)LocationError.InvalidParameter);
214 /// The distance between callback updates.
215 /// Should be in the range [1-120] meters.
217 /// <since_tizen>3</since_tizen>
218 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
219 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
220 public double Distance
224 Log.Info(Globals.LogTag, "Getting the Distance Interval");
229 Log.Info(Globals.LogTag, "Setting the Distance Interval");
230 if (value > 0 && value <= 120)
236 Log.Error(Globals.LogTag, "Error Setting the Distance");
237 throw LocationErrorFactory.ThrowLocationException((int)LocationError.InvalidParameter);
243 /// Gets the Location object.
245 /// <since_tizen>3</since_tizen>
246 public Location Location
250 Log.Info(Globals.LogTag, "Getting location details");
256 /// Gets the type used to obtain Location data.
258 /// <since_tizen>3</since_tizen>
259 public LocationType LocationType
263 Log.Info(Globals.LogTag, "Getting LocationType");
264 return _locationType;
269 /// Gets the status whether mock location is enabled or not.
271 /// <since_tizen>3</since_tizen>
272 /// <privilege>http://tizen.org/privilege/location</privilege>
273 /// <exception cref="UnauthroizedAccessException">Thrown when the app has no privilege to use the location.</exception>
274 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
275 public bool EnableMock
279 Log.Info(Globals.LogTag, "Getting getting Mock");
280 _isEnableMock = GetEnableMock();
281 return _isEnableMock;
285 _isEnableMock = value;
290 internal IntPtr GetHandle()
295 private bool GetEnableMock()
298 int ret = Interop.Locator.IsEnabledMock(out status);
299 if (((LocationError)ret != LocationError.None))
301 Log.Error(Globals.LogTag, "Error Get Enable Mock Status," + (LocationError)ret);
302 throw LocationErrorFactory.ThrowLocationException(ret);
307 private void SetEnableMock()
309 int ret = Interop.Locator.EnableMock(_isEnableMock);
310 if (((LocationError)ret != LocationError.None))
312 Log.Error(Globals.LogTag, "Error Set Enable Mock Status," + (LocationError)ret);
313 throw LocationErrorFactory.ThrowLocationException(ret);
318 /// Starts the Location Manager which has been created using the specified method.
320 /// <since_tizen>3</since_tizen>
321 /// <privilege>http://tizen.org/privilege/location</privilege>
322 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
323 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
324 /// <exception cref="UnauthroizedAccessException">Thrown when the app has no privilege to use the location.</exception>
325 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
328 Log.Info(Globals.LogTag, "Starting Location Manager");
329 if (_batchPeriod > 0 && _batchPeriod > _batchInterval)
331 int ret = Interop.Locator.StartBatch(_handle);
332 if (((LocationError)ret != LocationError.None))
334 Log.Error(Globals.LogTag, "Error Starting Location Batch mode," + (LocationError)ret);
335 throw LocationErrorFactory.ThrowLocationException(ret);
340 int ret = Interop.Locator.Start(_handle);
341 if (((LocationError)ret != LocationError.None))
343 Log.Error(Globals.LogTag, "Error Starting Location Manager," + (LocationError)ret);
344 throw LocationErrorFactory.ThrowLocationException(ret);
351 /// Stops the Location Manager which has been activated using the specified method.
352 /// Does not destroy the manager.
354 /// <since_tizen>3</since_tizen>
355 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
356 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
357 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
360 Log.Info(Globals.LogTag, "Stopping Location Manager");
361 int ret = Interop.Locator.Stop(_handle);
362 if (((LocationError)ret != LocationError.None))
364 Log.Error(Globals.LogTag, "Error stopping Location Manager," + (LocationError)ret);
365 throw LocationErrorFactory.ThrowLocationException(ret);
371 /// Sets a mock location for the given location method.
373 /// <since_tizen>3</since_tizen>
374 /// <param name="location"> The location object containing the mock location details.</param>
375 /// <privilege>http://tizen.org/privilege/location</privilege>
376 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
377 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
378 /// <exception cref="UnauthroizedAccessException">Thrown when the app has no privilege to use the location.</exception>
379 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
380 public void SetMockLocation(Location location)
382 Log.Info(Globals.LogTag, "Setting mock location");
383 int ret = Interop.Locator.SetMockLocation(_handle, location.Latitude, location.Longitude, location.Altitude, location.Speed, location.Direction, location.Accuracy);
384 if (((LocationError)ret == LocationError.None))
386 _location.Latitude = location.Latitude;
387 _location.Longitude = location.Longitude;
388 _location.Altitude = location.Altitude;
389 _location.Speed = location.Speed;
390 _location.Direction = location.Direction;
391 _location.Accuracy = location.Accuracy;
395 Log.Error(Globals.LogTag, "Error in setting up location mocking," + (LocationError)ret);
396 throw LocationErrorFactory.ThrowLocationException(ret);
401 /// Clears a mock location for the given location method.
403 /// <since_tizen>3</since_tizen>
404 /// <privilege>http://tizen.org/privilege/location</privilege>
405 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
406 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
407 /// <exception cref="UnauthroizedAccessException">Thrown when the app has no privilege to use the location.</exception>
408 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
409 public void ClearMock()
411 Log.Info(Globals.LogTag, "Clear mock location");
412 int ret = Interop.Locator.ClearMock(_handle);
413 if (((LocationError)ret != LocationError.None))
415 Log.Error(Globals.LogTag, "Error in clear up location mocking," + (LocationError)ret);
416 throw LocationErrorFactory.ThrowLocationException(ret);
421 /// Gets the details of the location asynchronously.
423 /// <since_tizen>3</since_tizen>
424 /// <param name="timeout"> Timeout to stop requesting single location after(seconds).</param>
425 /// <returns> A task which contains the current location details</returns>
426 /// <privilege>http://tizen.org/privilege/location</privilege>
427 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
428 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
429 /// <exception cref="UnauthroizedAccessException">Thrown when the app has no privilege to use the location.</exception>
430 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
431 public Task<Location> GetLocationAsync(int timeout)
433 var task = new TaskCompletionSource<Location>();
434 IntPtr id = IntPtr.Zero;
437 id = (IntPtr)_requestId++;
438 _callback_map[id] = (LocationError error, double latitude, double longitude, double altitude, int timestamp, double speed, double direction, double climb, IntPtr userData) =>
440 if (error != LocationError.None)
442 Log.Error(Globals.LogTag, "Error in getting up location information," + (LocationError)error);
446 Log.Info(Globals.LogTag, "Creating a current location object");
447 _location = new Location(latitude, longitude, altitude, speed, direction, 0.0, timestamp);
448 task.SetResult(_location);
452 _callback_map.Remove(userData);
457 int ret = Interop.LocatorEvent.GetSingleLocation(_handle, timeout, _callback_map[id], id);
458 if (((LocationError)ret != LocationError.None))
460 Log.Error(Globals.LogTag, "Error in setting up location mocking," + (LocationError)ret);
461 throw LocationErrorFactory.ThrowLocationException(ret);
468 /// Gets the details of the location.
470 /// <since_tizen>3</since_tizen>
471 /// <returns> which contains the current location details.</returns>
472 /// <privilege>http://tizen.org/privilege/location</privilege>
473 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
474 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
475 /// <exception cref="UnauthroizedAccessException">Thrown when the app has no privilege to use the location.</exception>
476 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
477 public Location GetLocation()
480 double longitude = 0;
484 double direction = 0;
492 Log.Info(Globals.LogTag, "Get current location information");
493 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);
494 if (((LocationError)ret != LocationError.None))
496 Log.Error(Globals.LogTag, "Error in get current location infomation," + (LocationError)ret);
497 throw LocationErrorFactory.ThrowLocationException(ret);
502 Log.Info(Globals.LogTag, "Get last location information");
503 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);
504 if (((LocationError)ret != LocationError.None))
506 Log.Error(Globals.LogTag, "Error in get last location information," + (LocationError)ret);
507 throw LocationErrorFactory.ThrowLocationException(ret);
511 Location location = new Location(latitude, longitude, altitude, speed, direction, accuracy, timestamp);
512 _location = location;
519 /// Adds a bounds for a given locator.
521 /// <since_tizen>3</since_tizen>
522 /// <param name="locationBoundary"> The boundary object to be added to the locator.</param>
523 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
524 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
525 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
526 public void AddBoundary(LocationBoundary locationBoundary)
528 Log.Info(Globals.LogTag, "AddBoundary called");
530 int ret = Interop.Locator.AddBoundary(_handle, locationBoundary.GetHandle());
531 if ((LocationBoundError)ret != LocationBoundError.None)
533 Log.Error(Globals.LogTag, "Error Adding Boundary," + (LocationBoundError)ret);
534 throw LocationErrorFactory.ThrowLocationBoundaryException(ret);
539 /// Deletes a bounds for a given locator.
541 /// <since_tizen>3</since_tizen>
542 /// <param name="locationBoundary"> The boundary object to be removed from the locator.</param>
543 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
544 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
545 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
546 public void RemoveBoundary(LocationBoundary locationBoundary)
548 Log.Info(Globals.LogTag, "RemoveBoundary called");
549 int ret = Interop.Locator.RemoveBoundary(_handle, locationBoundary.GetHandle());
550 if ((LocationBoundError)ret != LocationBoundError.None)
552 Log.Error(Globals.LogTag, "Error Removing Boundary," + (LocationBoundError)ret);
553 throw LocationErrorFactory.ThrowLocationBoundaryException(ret);
558 /// The overidden Dispose method of the IDisposable class.
560 /// <since_tizen>3</since_tizen>
561 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
562 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
563 public void Dispose()
566 GC.SuppressFinalize(this);
569 protected virtual void Dispose(bool disposing)
580 private void DestroyHandle()
582 int ret = Interop.Locator.Destroy(_handle);
583 if (((LocationError)ret != LocationError.None))
585 Log.Error(Globals.LogTag, "Error in Destroy handle, " + (LocationError)ret);
586 throw LocationErrorFactory.ThrowLocationException(ret);
591 /// (event) ServiceStateChanged Event is invoked when the location service state is changed.
593 /// <since_tizen>3</since_tizen>
594 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
595 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
596 public event EventHandler<ServiceStateChangedEventArgs> ServiceStateChanged
600 Log.Info(Globals.LogTag, "ServiceStateChanged called");
601 if (_serviceStateChanged == null)
603 Log.Info(Globals.LogTag, "Calling function SetServiceStateChangedCallback");
604 SetServiceStateChangedCallback();
606 _serviceStateChanged += value;
610 Log.Info(Globals.LogTag, "Callback removed");
611 _serviceStateChanged -= value;
613 if (_serviceStateChanged == null)
615 Log.Info(Globals.LogTag, "Calling function UnSetServiceStateChangedCallback");
616 UnSetServiceStateChangedCallback();
621 private void SetServiceStateChangedCallback()
623 Log.Info(Globals.LogTag, "Calling Interop.LocatorEvent.SetServiceStateChangedCallback");
624 if (_serviceStateChangedCallback == null)
626 _serviceStateChangedCallback = (state, userData) =>
628 Log.Info(Globals.LogTag, "Inside ServiceStateChangedCallback");
629 _serviceStateChanged?.Invoke(this, new ServiceStateChangedEventArgs(state));
633 int ret = Interop.LocatorEvent.SetServiceStateChangedCallback(_handle, _serviceStateChangedCallback, IntPtr.Zero);
634 if (((LocationError)ret != LocationError.None))
636 Log.Error(Globals.LogTag, "Error in Setting Service State Changed Callback," + (LocationError)ret);
637 throw LocationErrorFactory.ThrowLocationException(ret);
641 private void UnSetServiceStateChangedCallback()
643 Log.Info(Globals.LogTag, "Calling Interop.LocatorEvent.UnSetServiceStateChangedCallback");
644 int ret = Interop.LocatorEvent.UnSetServiceStateChangedCallback(_handle);
645 if (((LocationError)ret != LocationError.None))
647 Log.Error(Globals.LogTag, "Error in UnSetting Service State Changed Callback," + (LocationError)ret);
648 throw LocationErrorFactory.ThrowLocationException(ret);
653 /// (event) ZoneChanged is invoked when the previously set boundary area is entered or left.
655 /// <since_tizen>3</since_tizen>
656 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
657 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
658 public event EventHandler<ZoneChangedEventArgs> ZoneChanged
662 Log.Info(Globals.LogTag, "ZoneChanged called");
663 if (_zoneChanged == null)
665 Log.Info(Globals.LogTag, "Calling function SetZoneChangedCallback");
666 SetZoneChangedCallback();
668 _zoneChanged += value;
672 Log.Info(Globals.LogTag, "Callback removed");
673 _zoneChanged -= value;
675 if (_zoneChanged == null)
677 Log.Info(Globals.LogTag, "Calling function UnSetZoneChangedCallback");
678 UnSetZoneChangedCallback();
683 private void SetZoneChangedCallback()
685 Log.Info(Globals.LogTag, "Inside SetZoneChangedCallback");
686 if (_zoneChangedCallback == null)
688 _zoneChangedCallback = (state, latitude, longitude, altitude, timestamp, userData) =>
690 Log.Info(Globals.LogTag, "Inside ZoneChangedCallback");
691 DateTime timeStamp = DateTime.Now;
694 DateTime start = DateTime.SpecifyKind(new DateTime(1970, 1, 1).AddSeconds(timestamp), DateTimeKind.Utc);
695 timeStamp = start.ToLocalTime();
697 _zoneChanged?.Invoke(this, new ZoneChangedEventArgs(state, latitude, longitude, altitude, timeStamp));
701 int ret = Interop.LocatorEvent.SetZoneChangedCallback(_handle, _zoneChangedCallback, IntPtr.Zero);
702 if (((LocationError)ret != LocationError.None))
704 Log.Error(Globals.LogTag, "Error in Setting Zone Changed Callback," + (LocationError)ret);
705 throw LocationErrorFactory.ThrowLocationException(ret);
709 private void UnSetZoneChangedCallback()
711 Log.Info(Globals.LogTag, "Inside UnSetZoneChangedCallback");
712 int ret = Interop.LocatorEvent.UnSetZoneChangedCallback(_handle);
713 if (((LocationError)ret != LocationError.None))
715 Log.Error(Globals.LogTag, "Error in UnSetting Zone Changed Callback," + (LocationError)ret);
720 /// (event) SetttingChanged is raised when the location setting is changed.
722 /// <since_tizen>3</since_tizen>
723 /// <exception cref="InvalidOperationException">Thrown when the operation is invalid for the current state.</exception>
724 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
725 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
726 public event EventHandler<SettingChangedEventArgs> SettingChanged
730 Log.Info(Globals.LogTag, "Adding SettingChanged EventHandler");
731 if (_settingChanged == null)
733 Log.Info(Globals.LogTag, "Calling function SetSettingChangedCallback");
734 SetSettingChangedCallback();
736 _settingChanged += value;
740 Log.Info(Globals.LogTag, "Removing SettingChanged EventHandler");
741 _settingChanged -= value;
743 if (_settingChanged == null)
745 Log.Info(Globals.LogTag, "Calling function UnSetSettingChangedCallback");
746 UnSetSettingChangedCallback();
751 private void SetSettingChangedCallback()
753 Log.Info(Globals.LogTag, "Calling SetSettingChangedCallback");
754 if (_settingChangedCallback == null)
756 _settingChangedCallback = (method, enable, userData) =>
758 Log.Info(Globals.LogTag, "Calling SettingChangedCallback");
759 _settingChanged?.Invoke(this, new SettingChangedEventArgs(method, enable));
763 int ret = Interop.LocatorEvent.SetSettingChangedCallback((int)_locationType, _settingChangedCallback, IntPtr.Zero);
764 if (((LocationError)ret != LocationError.None))
766 Log.Error(Globals.LogTag, "Error in Setting Changed Callback," + (LocationError)ret);
767 throw LocationErrorFactory.ThrowLocationException(ret);
771 private void UnSetSettingChangedCallback()
773 Log.Info(Globals.LogTag, "Calling UnSetSettingChangedCallback");
774 int ret = Interop.LocatorEvent.UnSetSettingChangedCallback((int)_locationType);
775 if (((LocationError)ret != LocationError.None))
777 Log.Error(Globals.LogTag, "Error in Unsetting Setting's Callback," + (LocationError)ret);
778 throw LocationErrorFactory.ThrowLocationException(ret);
783 /// (event) DistanceBasedLocationChanged is raised with updated location information.
784 /// The callback will be invoked at minimum interval or minimum distance with updated position information.
786 /// <since_tizen>3</since_tizen>
787 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
788 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
789 public event EventHandler<LocationChangedEventArgs> DistanceBasedLocationChanged
793 Log.Info(Globals.LogTag, "Adding DistanceBasedLocationChanged EventHandler");
794 //if (_distanceBasedLocationChanged == null)
796 Log.Info(Globals.LogTag, "Calling function SetDistanceBasedLocationChangedCallback");
797 SetDistanceBasedLocationChangedCallback();
799 _distanceBasedLocationChanged += value;
803 Log.Info(Globals.LogTag, "Removing DistanceBasedLocationChanged EventHandler");
804 _distanceBasedLocationChanged -= value;
806 if (_distanceBasedLocationChanged == null)
808 Log.Info(Globals.LogTag, "Calling function UnSetDistanceBasedLocationChangedCallback");
809 UnSetDistanceBasedLocationChangedCallback();
814 private void SetDistanceBasedLocationChangedCallback()
816 Log.Info(Globals.LogTag, "SetDistanceBasedLocationChangedCallback");
817 if (_distanceBasedLocationChangedCallback == null) {
818 _distanceBasedLocationChangedCallback = (latitude, longitude, altitude, speed, direction, accuracy, timestamp, userData) =>
820 Log.Info(Globals.LogTag, "DistanceBasedLocationChangedCallback #1");
821 Location location = new Location(latitude, longitude, altitude, speed, direction, accuracy, timestamp);
822 Log.Info(Globals.LogTag, "DistanceBasedLocationChangedCallback #2");
823 _distanceBasedLocationChanged?.Invoke(this, new LocationChangedEventArgs(location));
824 Log.Info(Globals.LogTag, "DistanceBasedLocationChangedCallback #3");
828 int ret = Interop.LocatorEvent.SetDistanceBasedLocationChangedCallback(_handle, _distanceBasedLocationChangedCallback, _stayInterval, _distance, IntPtr.Zero);
829 if (((LocationError)ret != LocationError.None))
831 Log.Error(Globals.LogTag, "Error in Setting Distance based location changed Callback," + (LocationError)ret);
832 throw LocationErrorFactory.ThrowLocationException(ret);
836 private void UnSetDistanceBasedLocationChangedCallback()
838 Log.Info(Globals.LogTag, "UnSetDistanceBasedLocationChangedCallback");
839 int ret = Interop.LocatorEvent.UnSetDistanceBasedLocationChangedCallback(_handle);
840 if (((LocationError)ret != LocationError.None))
842 Log.Error(Globals.LogTag, "Error in UnSetting Distance based location changed Callback," + (LocationError)ret);
843 throw LocationErrorFactory.ThrowLocationException(ret);
845 _distanceBasedLocationChanged = null;
849 /// (event)LocationUpdated is raised at defined intervals of time with updated location information.
850 /// The callback will be invoked periodically.
852 /// <since_tizen>3</since_tizen>
853 /// <exception cref="ArgumentException">Thrown when an invalid argument is used.</exception>
854 /// <exception cref="NotSupportedException">Thrown when the location is not supported.</exception>
855 public event EventHandler<LocationChangedEventArgs> LocationChanged
859 Log.Info(Globals.LogTag, "Adding LocationChanged EventHandler");
860 if (_locationChanged == null)
862 if (_batchPeriod > 0 && _batchPeriod > _batchInterval)
864 Log.Info(Globals.LogTag, "Calling function SetLocationBatchCallback");
865 SetLocationBatchCallback();
869 Log.Info(Globals.LogTag, "Calling function SetLocationChangedCallback");
870 SetLocationChangedCallback();
873 _locationChanged += value;
877 Log.Info(Globals.LogTag, "Removing LocationChanged EventHandler");
878 _locationChanged -= value;
880 if (_locationChanged == null)
882 if (_batchPeriod > 0 && _batchPeriod > _batchInterval)
884 Log.Info(Globals.LogTag, "Calling function UnSetLocationBatchCallback");
885 UnSetLocationBatchCallback();
889 Log.Info(Globals.LogTag, "Calling function UnSetLocationChangedCallback");
890 UnSetLocationChangedCallback();
896 private void SetLocationChangedCallback()
898 Log.Info(Globals.LogTag, "Calling SetLocationChangedCallback");
900 if (_locationChangedCallback == null) {
901 _locationChangedCallback = (latitude, longitude, altitude, speed, direction, accuracy, timestamp, userData) =>
903 Log.Info(Globals.LogTag, "LocationChangedCallback has been called");
904 Location location = new Location(latitude, longitude, altitude, speed, direction, accuracy, timestamp);
905 _location = location;
906 _locationChanged?.Invoke(this, new LocationChangedEventArgs(location));
910 int ret = Interop.LocatorEvent.SetLocationChangedCallback(_handle, _locationChangedCallback, _interval, IntPtr.Zero);
911 if (((LocationError)ret != LocationError.None))
913 Log.Error(Globals.LogTag, "Error in Setting location changed Callback," + (LocationError)ret);
914 throw LocationErrorFactory.ThrowLocationException(ret);
918 private void UnSetLocationChangedCallback()
920 Log.Info(Globals.LogTag, "Calling UnSetLocationChangedCallback");
921 int ret = Interop.LocatorEvent.UnSetLocationChangedCallback(_handle);
922 if (((LocationError)ret != LocationError.None))
924 Log.Error(Globals.LogTag, "Error in UnSetting location changed Callback," + (LocationError)ret);
925 throw LocationErrorFactory.ThrowLocationException(ret);
929 private void SetLocationBatchCallback()
931 Log.Info(Globals.LogTag, "Calling SetLocationBatchCallback");
933 if (_locationBatchCallback == null) {
934 _locationBatchCallback = (batch_size, userData) =>
936 Log.Info(Globals.LogTag, "LocationBatchCallback has been called, size : " + batch_size);
938 _locationBatchGetCallback = (latitude, longitude, altitude, speed, direction, horizontal, vertical, timestamp, batchUserData) =>
940 Log.Info(Globals.LogTag, "GetLocationBatch has been called");
941 Location location = new Location(latitude, longitude, altitude, speed, direction, horizontal, timestamp);
942 _location = location;
943 _locationChanged?.Invoke(this, new LocationChangedEventArgs(location));
946 ret = Interop.LocatorEvent.GetLocationBatch(_handle, _locationBatchGetCallback, 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);
955 ret = Interop.LocatorEvent.SetLocationBatchCallback(_handle, _locationBatchCallback, _batchInterval, _batchPeriod, IntPtr.Zero);
956 if (((LocationError)ret != LocationError.None))
958 Log.Error(Globals.LogTag, "Error in Setting location batch Callback," + (LocationError)ret);
959 throw LocationErrorFactory.ThrowLocationException(ret);
963 private void UnSetLocationBatchCallback()
965 Log.Info(Globals.LogTag, "Calling UnSetLocationBatchCallback");
966 int ret = Interop.LocatorEvent.UnSetLocationBatchCallback(_handle);
967 if (((LocationError)ret != LocationError.None))
969 Log.Error(Globals.LogTag, "Error in UnSetting location batch Callback," + (LocationError)ret);
970 throw LocationErrorFactory.ThrowLocationException(ret);