Geolocation.GetLastKnownLocationAsync() 有时 returns null

Geolocation.GetLastKnownLocationAsync() sometimes returns null

这是在 iOS 12.1.4 上 iPhone 6s。通常 Geolocation.GetLastKnownLocationAsync() 有效,但有时无效。这是完全相同的代码,但如果我坐在这里一遍又一遍地按下我的 "get latitude and longitude" 按钮,最终 Geolocation.GetLastKnownLocationAsync() 会吐出一个空值。

你知道为什么会这样吗?我会如何处理?也许把它放在一个尝试十次的循环中,每次尝试之间等待一秒钟?

var location = await Essentials.Geolocation.GetLastKnownLocationAsync(); // works most of the time but sometimes it doesn't work.

这是我建议的解决方法:

Essentials.Location location = null;
for(var i = 0; i < 10; i++)
{
    location = await Essentials.Geolocation.GetLastKnownLocationAsync();
    if(location == null)
    {
        Thread.Sleep(1000);
    }
    else
    {
        break;
    }
}

首先,如果你真的需要一个 运行 循环,那么使用 Thread.Sleep 是非常糟糕的做法(除非你不在 main/UI 循环中)延迟,使用await Task.Delay(...。另外 iOS 上的 CLLocationManager 在主循环上 运行ning,如果您阻止它,消息泵将挂起并且位置管理器无法向应用程序报告。

由于 OS 速率限制,

"Spamming" CLLocationManager.Location(Essentials 在 iOS 上使用)可以(并且将)导致空 returns更新(主要是电池保护措施),如果 OS 正在启动 GPS 无线电以更新其位置,此方法将从 OS 开始超时,因此向 nil 报告 GetLastKnownLocationAsync 因此你得到 return of null.

CLLocationManager.Location on iOS 用于 quick 低功耗 return OS 到应用程序时会在应用程序启动、设备重启等时更新...并非每次调用它时都会更新。

You can get the last known location of the device by calling the GetLastKnownLocationAsync method. This is often faster then doing a full query, but can be less accurate.

否则,您应该使用 GetLocationAsync 来完全启动 GPS 以获得更新的准确位置。

To query the current device's location coordinates, the GetLocationAsync can be used. It is best to pass in a full GeolocationRequest and CancellationToken since it may take some time to get the device's location.

通常,我建议使用 GetLastKnownLocationAsync 作为让一般区域的用户知道这也可能 return null 的快速方法。然后继续在后台执行 GetLocationAsync(传递 GeolocationRequest 和 CancellationToken 实例)并根据更准确和最近的位置相应地更新应用程序。

回复:https://docs.microsoft.com/en-us/xamarin/essentials/geolocation?tabs=ios