Exemple #1
0
        public async Task <Location> GetLocationAsync(GeolocationRequest request, CancellationToken cancellationToken)
        {
            _ = request ?? throw new ArgumentNullException(nameof(request));

            if (!CLLocationManager.LocationServicesEnabled)
            {
                throw new FeatureNotEnabledException("Location services are not enabled on device.");
            }

            await Permissions.EnsureGrantedAsync <Permissions.LocationWhenInUse>();

            // the location manager requires an active run loop
            // so just use the main loop
            var manager = MainThread.InvokeOnMainThread(() => new CLLocationManager());

            var tcs = new TaskCompletionSource <CLLocation>(manager);

            var listener = new SingleLocationListener();

            listener.LocationHandler += HandleLocation;

            cancellationToken = Utils.TimeoutToken(cancellationToken, request.Timeout);
            cancellationToken.Register(Cancel);

            manager.DesiredAccuracy = request.PlatformDesiredAccuracy;
            manager.Delegate        = listener;

#if __IOS__
            // we're only listening for a single update
            manager.PausesLocationUpdatesAutomatically = false;
#endif

            manager.StartUpdatingLocation();

            var clLocation = await tcs.Task;

            return(clLocation?.ToLocation());

            void HandleLocation(CLLocation location)
            {
                manager.StopUpdatingLocation();
                tcs.TrySetResult(location);
            }

            void Cancel()
            {
                manager.StopUpdatingLocation();
                tcs.TrySetResult(null);
            }
        }
        public async Task <Location> GetLocationAsync(GeolocationRequest request, CancellationToken cancellationToken)
        {
            _ = request ?? throw new ArgumentNullException(nameof(request));

            if (!CLLocationManager.LocationServicesEnabled)
            {
                throw new FeatureNotEnabledException("Location services are not enabled on device.");
            }

            await Permissions.EnsureGrantedAsync <Permissions.LocationWhenInUse>();

            // the location manager requires an active run loop
            // so just use the main loop
            var manager = MainThread.InvokeOnMainThread(() => new CLLocationManager());

            var tcs = new TaskCompletionSource <CLLocation>(manager);

            var listener = new SingleLocationListener();

            listener.LocationHandler += HandleLocation;

            cancellationToken = Utils.TimeoutToken(cancellationToken, request.Timeout);
            cancellationToken.Register(Cancel);

            manager.DesiredAccuracy = request.PlatformDesiredAccuracy;
            manager.Delegate        = listener;

#if __IOS__
            // we're only listening for a single update
#pragma warning disable CA1416 // https://github.com/xamarin/xamarin-macios/issues/14619
            manager.PausesLocationUpdatesAutomatically = false;
#pragma warning restore CA1416
#endif

            manager.StartUpdatingLocation();

            var reducedAccuracy = false;
#if __IOS__
            if (OperatingSystem.IsIOSVersionAtLeast(14, 0))
            {
                if (request.RequestFullAccuracy && manager.AccuracyAuthorization == CLAccuracyAuthorization.ReducedAccuracy)
                {
                    await manager.RequestTemporaryFullAccuracyAuthorizationAsync("TemporaryFullAccuracyUsageDescription");
                }

                reducedAccuracy = manager.AccuracyAuthorization == CLAccuracyAuthorization.ReducedAccuracy;
            }
#endif

            var clLocation = await tcs.Task;

            return(clLocation?.ToLocation(reducedAccuracy));

            void HandleLocation(CLLocation location)
            {
                manager.StopUpdatingLocation();
                tcs.TrySetResult(location);
            }

            void Cancel()
            {
                manager.StopUpdatingLocation();
                tcs.TrySetResult(null);
            }
        }