Geolocation.GetLocationAsync 不工作

Geolocation.GetLocationAsync is not working

我有一个 Xamarin.Forms 支持 UWP、iOS 和 Android 的应用程序。具体来说,我现在正在 Android 模拟器上测试我的应用程序。为了获取位置,我使用 Xamarin.Essentials。这是我的代码片段:

在页面模型中:

                    bu = await GeolocationSrvc.GetBusinessUnitAsync();

下面是上述方法的实现:

    public static async Task<BusinessUnits> GetBusinessUnitAsync()
    {
        BusinessUnits bu = BusinessUnits.Aus;

        try
        {
            Location location = await GetLocation().ConfigureAwait(false);

            IEnumerable<Placemark> placemarks = await Geocoding.GetPlacemarksAsync(location);
            Placemark placemark = placemarks?.FirstOrDefault();
            string countryCode = placemark?.CountryCode;

            switch (countryCode)
            {
                case "AQ":
                case "AU":
                case "NZ":
                    bu = BusinessUnits.Aus;
                    break;
                default:
                    bu = BusinessUnits.NA;
                    break;
            }
        }
        catch (Exception)
        {
            throw;
        }

        return bu;
    }

    private static Task<Location> GetLocation()
    {
        GeolocationRequest request = new GeolocationRequest(GeolocationAccuracy.Medium, TimeSpan.FromSeconds(10));
        TaskCompletionSource<Location> locationTaskCompletionSource = new TaskCompletionSource<Location>();

        Device.BeginInvokeOnMainThread(async () =>
        {
            locationTaskCompletionSource.SetResult(await Geolocation.GetLocationAsync(request));
        });

        return locationTaskCompletionSource.Task;
    }

执行时

locationTaskCompletionSource.SetResult(await Geolocation.GetLocationAsync(request));

系统询问我是否要允许该应用获取我的位置。如果我按是,它会按预期工作。但是,如果我按否,则永远不会返回该位置(甚至不返回 null),也永远不会执行以下代码。我希望在回答否的情况下使用

中设置的默认值
BusinessUnits bu = BusinessUnits.Aus;

但这并没有发生。

您没有设置 TaskCompletionSource 对象的 Exception

private static Task<Location> GetLocation()
{
    GeolocationRequest request = new GeolocationRequest(GeolocationAccuracy.Medium, TimeSpan.FromSeconds(10));
    TaskCompletionSource<Location> locationTaskCompletionSource = new TaskCompletionSource<Location>();

    Device.BeginInvokeOnMainThread(async () =>
    {
        try
        {
            locationTaskCompletionSource.SetResult(await Geolocation.GetLocationAsync(request));
        }
        catch(Exception exception)
        {
            locationTaskCompletionSource.SetException(exception);
            locationTaskCompletionSource.SetResult(null);
        }
    });

    return locationTaskCompletionSource.Task;
}

替代方法是使用每个平台的简单依赖服务事先检查位置权限。

如果权限被授予,则继续位置获取。否则提示用户获取权限。

例如。 Android 检查位置权限的实现:

public bool IsLocationPermissionGranted()
{
    if (ContextCompat.CheckSelfPermission(Application.Context, 
    Manifest.Permission.AccessFineLocation) == Permission.Granted)
    {
        return true;
    }
    return false;
}