简体   繁体   中英

Weird problem getting device's location with Xamarin.Essentials Geolocation in Xamarin.Forms.Maps on iOS

I'm having a weird problem on iOS only , I'm using Xamarin.Forms.Maps ( copy paste from docs ), my iOS simulator has its Mock location to "Apple" and I'm using Xamarin.Essentials Geolocation to get the device's location:

private async Task ExecuteDisplayCurrentLocationCommand()
    {
        IsBusy = true;

        try
        {
            MainThread.BeginInvokeOnMainThread(async () =>
            {
                var request = new GeolocationRequest(GeolocationAccuracy.High, TimeSpan.FromSeconds(10));
                var cts = new CancellationTokenSource();
                var location = await Geolocation.GetLocationAsync(request, cts.Token);

                if (location != null)
                {
                    if (location.IsFromMockProvider)
                    {
                        //await App.Current.MainPage.DisplayAlert("Wrong Location", "Your device is giving a false location, please turn on location services in the settings", "Cancel");
                        Position position1 = new Position(location.Latitude, location.Longitude);
                        MapSpan mapSpan1 = MapSpan.FromCenterAndRadius(position1, Distance.FromKilometers(8));
                        Map.MoveToRegion(mapSpan1);
                    }
                    Position position = new Position(location.Latitude, location.Longitude);
                    MapSpan mapSpan = MapSpan.FromCenterAndRadius(position, Distance.FromKilometers(8));
                    Map.MoveToRegion(mapSpan);
                }
                //else
                //{
                //    await App.Current.MainPage.DisplayAlert("Can't get location", "", "Cancel");
                //}
            });
        }
        catch (FeatureNotSupportedException)
        {
            await App.Current.MainPage.DisplayAlert("Location feature not supported", "Your device doesn't support location, please use a newer device", "Ok");
        }
        catch (FeatureNotEnabledException)
        {
            //await App.Current.MainPage.DisplayAlert("Location isn't enabled", "Your device doesn't have location services enabed, please turn on location services in the settings", "Ok");
        }
        catch (PermissionException)
        {
            await App.Current.MainPage.DisplayAlert("Location permission", "Your device isn't giving us permission to use your location, please turn on location services in the settings", "Ok");
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex);
        }
        finally
        {
            IsBusy = false;
        }
    }

I'm using MainThread.BeginInvokeOnMainThread because it is required on iOS for it to work

What's weird is that when I run the code and it reaches the Map.MoveToRegion(mapSpan); in the if (location.IsFromMockProvider) method, it goes to the CustomMapRenderer 's GetViewForAnnotation and runs the var customPin = GetCustomPin(annotation as MKPointAnnotation); method as if it was trying to get the map pins which doesn't make sense to me, which throws a System.Reflection.TargetInvocationException because the CustomPin GetCustomPin(MKPointAnnotation annotation) 's annotation argument is null, of course it's not supposed to call it right?

What's weird is that the call to the method: var customPin = GetCustomPin2(annotation as MKPointAnnotation); actually passes the lat and lon as parameters, I'm confused.

Should it call it in the first place?

Does anyone knows why it does that? I haven't had this problem on Android and can't check if it does the same on Android at the moment but if anyone knows why it does that and what the solution is please help.

Thank you

Does the problem persists if you remove the plugin Xamarin.Essentials Geolocation ?

Have you tried on a real device?


Look at the definition(copy from docs)

The GetViewForAnnotation method is called when the location of the annotation becomes visible on the map, and is used to customize the annotation prior to display.

This method should not be called if you don't set Pins on map.

Try to add the following code

if(annotation == null)  return null;  //add this line
var customPin = GetCustomPin(annotation as MKPointAnnotation);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM