不在 UI 线程上时如何请求权限?
How do i request permissions when not on the UI thread?
我目前使用的是最新版本的 Xamarin.Forms (4.5.0.617) 和 Xamarin.Essentials (1.5.2)。
我有一个依赖注入服务,负责获取对 phone 联系人的访问权限,它实际上是 Xamarin.Essentials 权限代码的包装器。我需要保证代码在 UI 线程上执行以避免异常。我已经了解了以下代码,但是,它并没有像我预期的那样工作。在我的应用程序中,权限弹出窗口出现并为我提供了选择 allow/deny 但是 RequestAsync 之后的所有代码都无法执行,就像从未正式返回响应一样。下次我 运行 该应用程序时,它会立即运行(因此大概已正确记录后台权限)。
public async Task<bool> RequestAccessPhoneContacts()
{
PermissionStatus status = PermissionStatus.Denied;
status = await MainThread.InvokeOnMainThreadAsync<PermissionStatus>(async () =>
{
return await Permissions.RequestAsync<Permissions.ContactsRead>();
});
return (status == PermissionStatus.Granted);
}
我不确定我尝试将代码强制到 UI 线程的方式是否导致了问题,或者我是否错误地使用了异步代码...或者(最不可能)它是否是 Xamarin.Essentials 权限代码中的错误。我目前只在 Android 上看到过这种行为,但我还没有在其他任何人身上测试过。
非常感谢任何帮助:)
谢谢!
原来我在设置时没有正确遵循文档。
将其添加到我的主 activity 后,一切都恢复了生机。
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Android.Content.PM.Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
此信息来自我在 Xamarin.Essentials github 上提出的错误 -
https://github.com/xamarin/Essentials/issues/1227
当我使用 Xamarin.Essentials 呼叫当前位置时,我遇到了类似的问题。我得到这个例外:
Xamarin.Essentials.PermissionException: 'Permission request must be invoked on main thread.'
&帮我解决了
从主线程调用当前位置
private Task<Location> GetLastKnownLocation()
{
var locationTaskCompletionSource = new TaskCompletionSource<Location>();
Device.BeginInvokeOnMainThread(async () =>
{
locationTaskCompletionSource.SetResult(await Geolocation.GetLastKnownLocationAsync());
});
return locationTaskCompletionSource.Task;
}
并在 Try catch 块中调用上述方法并使用 configure await false
private async Task ExecuteGetGeoLocationCommand()
{
try
{
var location = await GetLastKnownLocation().ConfigureAwait(false);
}
catch (FeatureNotSupportedException fnsEx) {}
catch (Exception ex){}
}
我目前使用的是最新版本的 Xamarin.Forms (4.5.0.617) 和 Xamarin.Essentials (1.5.2)。
我有一个依赖注入服务,负责获取对 phone 联系人的访问权限,它实际上是 Xamarin.Essentials 权限代码的包装器。我需要保证代码在 UI 线程上执行以避免异常。我已经了解了以下代码,但是,它并没有像我预期的那样工作。在我的应用程序中,权限弹出窗口出现并为我提供了选择 allow/deny 但是 RequestAsync 之后的所有代码都无法执行,就像从未正式返回响应一样。下次我 运行 该应用程序时,它会立即运行(因此大概已正确记录后台权限)。
public async Task<bool> RequestAccessPhoneContacts()
{
PermissionStatus status = PermissionStatus.Denied;
status = await MainThread.InvokeOnMainThreadAsync<PermissionStatus>(async () =>
{
return await Permissions.RequestAsync<Permissions.ContactsRead>();
});
return (status == PermissionStatus.Granted);
}
我不确定我尝试将代码强制到 UI 线程的方式是否导致了问题,或者我是否错误地使用了异步代码...或者(最不可能)它是否是 Xamarin.Essentials 权限代码中的错误。我目前只在 Android 上看到过这种行为,但我还没有在其他任何人身上测试过。
非常感谢任何帮助:)
谢谢!
原来我在设置时没有正确遵循文档。
将其添加到我的主 activity 后,一切都恢复了生机。
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Android.Content.PM.Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
此信息来自我在 Xamarin.Essentials github 上提出的错误 - https://github.com/xamarin/Essentials/issues/1227
当我使用 Xamarin.Essentials 呼叫当前位置时,我遇到了类似的问题。我得到这个例外:
Xamarin.Essentials.PermissionException: 'Permission request must be invoked on main thread.'
&
从主线程调用当前位置
private Task<Location> GetLastKnownLocation() { var locationTaskCompletionSource = new TaskCompletionSource<Location>(); Device.BeginInvokeOnMainThread(async () => { locationTaskCompletionSource.SetResult(await Geolocation.GetLastKnownLocationAsync()); }); return locationTaskCompletionSource.Task; }
并在 Try catch 块中调用上述方法并使用 configure await false
private async Task ExecuteGetGeoLocationCommand() { try { var location = await GetLastKnownLocation().ConfigureAwait(false); } catch (FeatureNotSupportedException fnsEx) {} catch (Exception ex){} }