我的Xamarin.Forms应用程序上的GetLocationAsync失败。
我有最新的Xamarin.Essentials nuget包。
我已经在info.plist中设置了必要的权限。
我从我的ViewModel调用它。
这个电话非常简单:
var location = await Geolocation.GetLastKnownLocationAsync();
但它既失败又无法提示用户权限对话框,即使我的info.plist已正确设置:NSLocationWhenInUseUsageDescription插入原因
我问并回答这个问题,因为这是一个令人头疼的问题,我不确定要搜索什么或问题是什么。
我的各种搜索指向了许多相关问题,但实际上并没有找到主要问题。
我得到的最接近的是Essentials github页面上的这个问题:https://github.com/xamarin/Essentials/issues/634
这个答案的灵感来自于Xamarin / Azure布道者布兰登·明尼克 - >看看他的项目,他处理类似情况下面的code:
那么我们可以从上面拿走什么呢?如果你看一下上下文,他已将他的Views与MVVM风格的ViewModels联系起来。但是,各种库要求从主线程调用某些方法。这是问题的本质,这就是这段代码可以解决的问题。
因此,对于问题中提到的地理定位问题采用上述代码,我做了以下内容:
Task<Xamarin.Essentials.Location> GetLocationFromPhone()
{
var locationTaskCompletionSource = new TaskCompletionSource<Xamarin.Essentials.Location>();
Device.BeginInvokeOnMainThread(async () =>
{
locationTaskCompletionSource.SetResult(await Geolocation.GetLastKnownLocationAsync());
});
return locationTaskCompletionSource.Task;
}
我在一个Task中使用了我的ViewModel中的上述内容。像下面这样的东西。
async Task ExecuteGetGeoLocationCommand()
{
try
{
var locationFromPhone = await GetLocationFromPhone().ConfigureAwait(false);
if (locationFromPhone is null)
return;
_location = locationFromPhone;
if (_location != null)
{
Console.WriteLine($"Latitude: {_location.Latitude}, Longitude {_location.Longitude}, Altitude: {_location.Altitude}");
}
else
{
Console.WriteLine($"Exiting geolocation");
}
catch (FeatureNotSupportedException fnsEx)
{
}
catch (Exception ex)
{
}
}
}
我希望它对别人有帮助!
如果您正在使用Xamarin.Essentials并且未在Android上提示您获得权限,请确保已将所有必需的代码添加到Android主要活动中。
有关详细信息,请参阅https://docs.microsoft.com/en-us/xamarin/essentials/get-started?tabs=windows%2Candroid。
来自文档:
protected override void OnCreate(Bundle savedInstanceState) {
//...
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState); // add this line to your code, it may also be called: bundle
//...
和
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}