Example #1
0
        public async Task <bool> StartListeningAsync(TimeSpan minimumTime, double minimumDistance, bool includeHeading = false, ListenerSettings listenerSettings = null)
        {
            var hasPermission = await CheckPermissions();

            if (!hasPermission)
            {
                throw new GeolocationException(GeolocationError.Unauthorized);
            }


            var minTimeMilliseconds = minimumTime.TotalMilliseconds;

            if (minTimeMilliseconds < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(minimumTime));
            }
            if (minimumDistance < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(minimumDistance));
            }
            if (IsListening)
            {
                throw new InvalidOperationException("This Geolocator is already listening");
            }

            var providers = Providers;

            listener = new GeolocationContinuousListener(Manager, minimumTime, providers);
            listener.PositionChanged += OnListenerPositionChanged;
            listener.PositionError   += OnListenerPositionError;

            var looper = Looper.MyLooper() ?? Looper.MainLooper;

            listeningProviders.Clear();
            for (var i = 0; i < providers.Length; ++i)
            {
                var provider = providers[i];

                //we have limited set of providers
                if (ProvidersToUseWhileListening != null &&
                    ProvidersToUseWhileListening.Length > 0)
                {
                    //the provider is not in the list, so don't use it.
                    if (!ProvidersToUseWhileListening.Contains(provider))
                    {
                        continue;
                    }
                }


                listeningProviders.Add(provider);
                Manager.RequestLocationUpdates(provider, (long)minTimeMilliseconds, (float)minimumDistance, listener, looper);
            }
            return(true);
        }
Example #2
0
        /// <summary>
        /// Start listening for changes
        /// </summary>
        /// <param name="minimumTime">Time</param>
        /// <param name="minimumDistance">Distance</param>
        /// <param name="includeHeading">Include heading or not</param>
        /// <param name="listenerSettings">Optional settings (iOS only)</param>
        public async Task <bool> StartListeningAsync(TimeSpan minimumTime, double minimumDistance, bool includeHeading = false, ListenerSettings listenerSettings = null)
        {
            if (minimumDistance < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(minimumDistance));
            }

            if (isListening)
            {
                throw new InvalidOperationException("Already listening");
            }

            // if no settings were passed in, instantiate the default settings. need to check this and create default settings since
            // previous calls to StartListeningAsync might have already configured the location manager in a non-default way that the
            // caller of this method might not be expecting. the caller should expect the defaults if they pass no settings.
            if (listenerSettings == null)
            {
                listenerSettings = new ListenerSettings();
            }

#if __IOS__
            var permission = Permission.Location;
            if (UIDevice.CurrentDevice.CheckSystemVersion(9, 0))
            {
                if (listenerSettings.AllowBackgroundUpdates)
                {
                    permission = Permission.LocationAlways;
                }
                else
                {
                    permission = Permission.LocationWhenInUse;
                }
            }

            var hasPermission = await CheckPermissions(permission);


            if (!hasPermission)
            {
                throw new GeolocationException(GeolocationError.Unauthorized);
            }
#endif

            // keep reference to settings so that we can stop the listener appropriately later
            this.listenerSettings = listenerSettings;

            var desiredAccuracy = DesiredAccuracy;

// set background flag
#if __IOS__
            if (UIDevice.CurrentDevice.CheckSystemVersion(9, 0))
            {
                manager.AllowsBackgroundLocationUpdates = listenerSettings.AllowBackgroundUpdates;
            }

            // configure location update pausing
            if (UIDevice.CurrentDevice.CheckSystemVersion(6, 0))
            {
                manager.PausesLocationUpdatesAutomatically = listenerSettings.PauseLocationUpdatesAutomatically;

                switch (listenerSettings.ActivityType)
                {
                case ActivityType.AutomotiveNavigation:
                    manager.ActivityType = CLActivityType.AutomotiveNavigation;
                    break;

                case ActivityType.Fitness:
                    manager.ActivityType = CLActivityType.Fitness;
                    break;

                case ActivityType.OtherNavigation:
                    manager.ActivityType = CLActivityType.OtherNavigation;
                    break;

                default:
                    manager.ActivityType = CLActivityType.Other;
                    break;
                }
            }
#endif

            // to use deferral, CLLocationManager.DistanceFilter must be set to CLLocationDistance.None, and CLLocationManager.DesiredAccuracy must be
            // either CLLocation.AccuracyBest or CLLocation.AccuracyBestForNavigation. deferral only available on iOS 6.0 and above.
            if (CanDeferLocationUpdate && listenerSettings.DeferLocationUpdates)
            {
                minimumDistance = CLLocationDistance.FilterNone;
                desiredAccuracy = CLLocation.AccuracyBest;
            }

            isListening             = true;
            manager.DesiredAccuracy = desiredAccuracy;
            manager.DistanceFilter  = minimumDistance;

#if __IOS__ || __MACOS__
            if (listenerSettings.ListenForSignificantChanges)
            {
                manager.StartMonitoringSignificantLocationChanges();
            }
            else
            {
                manager.StartUpdatingLocation();
            }
#elif __TVOS__
            //not supported
#endif

#if __IOS__
            if (includeHeading && CLLocationManager.HeadingAvailable)
            {
                manager.StartUpdatingHeading();
            }
#endif

            return(true);
        }