来自 Xamarin Forms 的 Geolocation GetLastKnownLocationAsync() 权限异常 - 调用失败并且没有权限提示
Geolocation GetLastKnownLocationAsync() permission exception from Xamarin Forms - call fails and no permission prompt
GetLocationAsync 在我的 Xamarin.Forms 应用上失败。
我有最新的 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 布道者 Brandon Minnick --> 看看他的项目,他在其中处理类似情况 code:
那么我们可以从上面得到什么?如果您查看上下文,他会以 MVVM 样式将他的视图与他的 ViewModel 连接起来。但是,各种库要求从主线程调用某些方法。这就是问题的本质,这就是这段代码可以解决的问题。
因此,为了采用上述代码解决问题中提到的地理定位问题,我做了以下操作:
Task<Xamarin.Essentials.Location> GetLocationFromPhone()
{
var locationTaskCompletionSource = new TaskCompletionSource<Xamarin.Essentials.Location>();
Device.BeginInvokeOnMainThread(async () =>
{
locationTaskCompletionSource.SetResult(await Geolocation.GetLastKnownLocationAsync());
});
return locationTaskCompletionSource.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 主 Activity.
详情见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);
}
GetLocationAsync 在我的 Xamarin.Forms 应用上失败。
我有最新的 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 布道者 Brandon Minnick --> 看看他的项目,他在其中处理类似情况 code:
那么我们可以从上面得到什么?如果您查看上下文,他会以 MVVM 样式将他的视图与他的 ViewModel 连接起来。但是,各种库要求从主线程调用某些方法。这就是问题的本质,这就是这段代码可以解决的问题。
因此,为了采用上述代码解决问题中提到的地理定位问题,我做了以下操作:
Task<Xamarin.Essentials.Location> GetLocationFromPhone()
{
var locationTaskCompletionSource = new TaskCompletionSource<Xamarin.Essentials.Location>();
Device.BeginInvokeOnMainThread(async () =>
{
locationTaskCompletionSource.SetResult(await Geolocation.GetLastKnownLocationAsync());
});
return locationTaskCompletionSource.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 主 Activity.
详情见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);
}