我很困惑,如果需要异步,我应该如何在 Android 应用程序的主线程上请求权限访问。我想在我的应用程序打开后立即执行此操作,但我收到以下错误:"Permission request must be invoked on main thread."我该如何执行此操作?我的理解是,这RequestAsync需要一个单独的线程(因为它是一个异步方法调用)。
public partial class SplashPage : ContentPage
{
PermissionStatus LocationPermission;
public SplashPage()
{
InitializeComponent();
LocationPermission = PermissionStatus.Unknown;
}
protected override void OnAppearing()
{
var result = Task.Run(async () => await CheckLocationPermission());
result.Wait();
var resultval = result.Result;
result = Task.Run(async () => await RequestLocationPermission());
result.Wait();
}
public async Task<PermissionStatus> CheckLocationPermission()
{
LocationPermission = await Permissions.CheckStatusAsync<Permissions.LocationWhenInUse>();
return LocationPermission;
}
public async Task<PermissionStatus> RequestLocationPermission()
{
try
{
if (LocationPermission == PermissionStatus.Granted)
return LocationPermission;
if (Permissions.ShouldShowRationale<Permissions.LocationWhenInUse>())
{
await Shell.Current.DisplayAlert("Needs Permissions", "BECAUSE!!!", "OK");
}
LocationPermission = await Permissions.RequestAsync<Permissions.LocationWhenInUse>();
}
catch (Exception ex)
{
//Error that permissions request must be on main thread **
Console.WriteLine(ex.Message);
}
return LocationPermission;
}
}
Run Code Online (Sandbox Code Playgroud)
AppShell.xaml:
<?xml version="1.0" encoding="UTF-8" ?>
<Shell
x:Class="CellularSignal1.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:CellularSignal1"
Shell.FlyoutBehavior="Disabled">
<TabBar x:Name="MyTabBar">
<Tab x:Name="CellularInfo" Title="Cellular Info">
<ShellContent ContentTemplate="{DataTemplate local:SplashPage}" Route="SplashPage"/>
<ShellContent ContentTemplate="{DataTemplate local:CellularInfo}" Route="CellularInfo"/>
<ShellContent ContentTemplate="{DataTemplate local:BSInfo}" Route="BSInfo"/>
</Tab>
</TabBar>
</Shell>
Run Code Online (Sandbox Code Playgroud)
AppShell.xaml.cs:
namespace CellularSignal1;
#if ANDROID
public partial class AppShell : Shell
{
public AppShell()
{
InitializeComponent();
}
}
#endif
Run Code Online (Sandbox Code Playgroud)
您应该OnAppearing()覆盖方法async和await调用。不需要通过以下方式创建的线程池Task.Run()线程:
protected override async void OnAppearing()
{
var resultCheck = await CheckLocationPermission();
var resultRequest = await RequestLocationPermission();
}
Run Code Online (Sandbox Code Playgroud)
一般来说,当你遇到像上面提到的主线程这样的错误时,并不意味着代码需要它自己的线程,而是代码必须在MainThread,这是一个特殊的线程上执行。
您可以从任何其他线程(不是主线程)调用主线程上的代码,如下所示:
private async Task SomeMethodAsync()
{
await MainThread.InvokeOnMainThreadAsync(async () =>
{
var resultCheck = await CheckLocationPermission();
var resultRequest = await RequestLocationPermission();
});
}
Run Code Online (Sandbox Code Playgroud)
注意:在您的情况下,后者不是必需的,因为它OnAppearing()已经在主线程上执行。
| 归档时间: |
|
| 查看次数: |
1834 次 |
| 最近记录: |