在 iOS 上的 Xamarin.Forms.Maps 中使用 Xamarin.Essentials Geolocation 获取设备位置的奇怪问题

Posted

技术标签:

【中文标题】在 iOS 上的 Xamarin.Forms.Maps 中使用 Xamarin.Essentials Geolocation 获取设备位置的奇怪问题【英文标题】:Weird problem getting device's location with Xamarin.Essentials Geolocation in Xamarin.Forms.Maps on iOS 【发布时间】:2022-01-19 06:58:46 【问题描述】:

我遇到了一个奇怪的问题仅在 iOS 上,我正在使用 Xamarin.Forms.Maps(从 docs 复制粘贴),我的 ios 模拟器的 Mock 位置为“Apple”,我'正在使用 Xamarin.Essentials Geolocation 来获取设备的位置:

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;
        
    

我正在使用MainThread.BeginInvokeOnMainThread,因为它需要在 iOS 上才能工作

奇怪的是,当我运行代码并到达if (location.IsFromMockProvider) 方法中的Map.MoveToRegion(mapSpan); 时,它会转到CustomMapRendererGetViewForAnnotation 并运行var customPin = GetCustomPin(annotation as MKPointAnnotation); 方法,就好像它正在尝试一样获取对我来说没有意义的地图图钉,这会引发System.Reflection.TargetInvocationException,因为CustomPin GetCustomPin(MKPointAnnotation annotation)annotation 参数为空,当然它不应该调用它对吗?

奇怪的是对方法的调用:var customPin = GetCustomPin2(annotation as MKPointAnnotation); 实际上将 lat 和 lon 作为参数传递,我很困惑。

它应该首先调用它吗?

有谁知道为什么会这样?我在 android 上没有遇到过这个问题,目前无法检查它是否在 Android 上也有同样的问题,但如果有人知道为什么会这样以及解决方案是什么,请提供帮助。

谢谢

编辑

正如 Cole-MSFT 所说,我在 GetCustomPin 方法中添加了一个空语句并且它起作用了

CustomPin GetCustomPin(MKPointAnnotation annotation)
    
        Position position;

        if (annotation != null)
        
            position = new Position(annotation.Coordinate.Latitude, annotation.Coordinate.Longitude);
            if (position != null)
            
                foreach (var pin in customPins)
                
                    if (pin.Position == position)
                    
                        return pin;
                    
                
            
        
        else
        
            return null;
        

        return null;
    

【问题讨论】:

如果您启用了地图视图以显示用户的位置,那么您就有机会用您自己的替换标准的“蓝点”注释。您需要检查您被要求处理的注释类型。如果是MKUserAnnotation,则返回nil,使用标准蓝点 【参考方案1】:

如果您删除插件Xamarin.Essentials Geolocation ,问题是否仍然存在?

你在真机上试过了吗?


查看定义(从文档复制)

当注解的位置在地图上可见时调用GetViewForAnnotation方法,用于在显示之前自定义注解。

如果您没有在地图上设置Pins,则不应调用此方法。

尝试添加以下代码

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

【讨论】:

正是我在 GetCustomPin 方法中添加了一个空语句,它起作用了,感谢您的回答!

以上是关于在 iOS 上的 Xamarin.Forms.Maps 中使用 Xamarin.Essentials Geolocation 获取设备位置的奇怪问题的主要内容,如果未能解决你的问题,请参考以下文章

图像无法在 iOS 上的 Safari 上加载

在 iOS 上的 Safari 中全屏打开网页

XING - 如何在 iOS 上的 Android 上进行深度链接?

在电脑上调试苹果ios上的h5页面

如何在 iOS 7.1 中更改 TabBar 上的图像和标签颜色?

iOS 14 上的 NSNumberFormatter 错误