Xamarin.Android ZXing.Net.Mobile 的相机权限仅在应用重启后有效

Xamarin.Android Camera Permissions with ZXing.Net.Mobile only works after app restart

我在 Xamarin.Forms 项目中使用 ZXing.Net.Mobile。它在 iOS 上运行良好,但在 Android 上,我第一次使用扫描仪时,弹出相机权限,并授予它们。

获得权限后相机没有图像。如果我退出应用程序并重新启动,相机从那时起就可以正常工作。我怎样才能让它立即工作?即使我关闭我的视图,处理并重新初始化它,它仍然无法工作,直到应用程序重新启动。

相关代码如下:

public partial class CEUScanModalPage : ContentPage, INotifyPropertyChanged {
    private bool _isScanning;

    public CEUScanModalPage() {
        InitializeComponent();
        IsScanning = false;
        BindingContext = this;
        Indicator.Start();
    }

    public bool IsScanning {
        get {
            return _isScanning;
        }
        set {
            _isScanning = value;
            OnPropertyChanged();
        }
    }

    private async void OnCloseButtonClicked(object sender, EventArgs args) {
        await Navigation.PopModalAsync();
    }

    protected override void OnAppearing() {
        base.OnAppearing();
        IsScanning = true;
    }

    protected override void OnDisappearing() {
        base.OnDisappearing();
        _scanView.OnScanResult -= Handle_OnScanResult;
        _scanView.IsAnalyzing = false;
        _scanView.IsScanning = false;
        ParentGrid.Children.Remove(_scanView);
        _scanView = null;
    }

    public async void Handle_OnScanResult(Result result) {
        IsScanning = false;

      
    }
}

XAML:

<?xml version="1.0" encoding="UTF-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:BehaviorLive" xmlns:grial="clr-namespace:UXDivers.Grial;assembly=UXDivers.Grial" xmlns:ffimageloading="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms" xmlns:fftransformations="clr-namespace:FFImageLoading.Transformations;assembly=FFImageLoading.Transformations" xmlns:zxing="clr-namespace:ZXing.Net.Mobile.Forms;assembly=ZXing.Net.Mobile.Forms"

    x:Class="BehaviorLive.Views.CEUScanModalPage"
                NavigationPage.HasNavigationBar="False"
    Style="{ StaticResource MainMenuOrModalBackgroundStyle }">
    <ContentPage.Resources>
        <ResourceDictionary
            Source="/Styles/TabControl/SimpleTabResources.xaml" />
    </ContentPage.Resources>

    <ContentPage.Content>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition
                    Height="145" />
                <RowDefinition
                    Height="*" />
            </Grid.RowDefinitions>

            <Grid
                RowSpacing="0"
                ColumnSpacing="0"
                Margin="0,0,0,10"
                VerticalOptions="EndAndExpand">
                <Grid.RowDefinitions>
                    <RowDefinition
                        Height="10" />
                    <RowDefinition
                        Height="Auto" />
                    <RowDefinition
                        Height="Auto" />
                </Grid.RowDefinitions>

                <Grid.ColumnDefinitions>
                    <ColumnDefinition
                        Width="120" />
                    <ColumnDefinition
                        Width="*" />
                </Grid.ColumnDefinitions>

                <!-- LOGO -->
                <Label
                    Grid.Row="0"
                    Grid.RowSpan="3"
                    Margin="20,0"
                    TextColor="{ DynamicResource InverseTextColor }"
                    FontSize="74"
                     FontFamily="{StaticResource FontAwesomeSolid}"
                    Text="{ x:Static local:FontawesomeSolidFont.Qrcode }"
                    Style="{ StaticResource FontIcon }"
                    HorizontalOptions="Start"
                    VerticalTextAlignment="Center" />

                <!-- WELCOME -->
                <Label
                    Grid.Row="1"
                    Grid.Column="1"
                    Text="CEU Checkin"
                    FontSize="22"
                    TextColor="{ DynamicResource InverseTextColor }"
                    Style="{ StaticResource LabelBoldStyle }"
                    VerticalOptions="End"
                    HorizontalOptions="Start" />

                <!-- SUB -->
                <Label
                    Grid.Row="2"
                    Grid.Column="1"
                    Text="Scan QR Code to check in/out of your event"
                    FontSize="16"
                    TextColor="{ DynamicResource InverseTextColor }"
                    VerticalOptions="Start"
                    HorizontalOptions="Start" />
            </Grid>

            <Grid
                Grid.Row="1"
                BackgroundColor="{ DynamicResource MainWrapperBackgroundColor }"
                grial:Effects.ApplyIOSSafeAreaAsPadding="Bottom" x:Name="ParentGrid">
                <!-- TAB -->

                <StackLayout x:Name="LoadingIndicator" Grid.Row="0" VerticalOptions="CenterAndExpand">
                    <local:CustomActivityIndicator
                        Grid.Row="0"

                        x:Name="Indicator"
                        HorizontalOptions="Center"
                        VerticalOptions="Start" />

                    <Label
                        Grid.Row="1"
                        FontSize="Large"
                        HorizontalTextAlignment="Center"
                        Text="{ grial:Translate StringLoading }" />
                </StackLayout>

                <zxing:ZXingScannerView Grid.Row="0" Grid.RowSpan="2" x:Name="_scanView" OnScanResult="Handle_OnScanResult" IsScanning="{Binding IsScanning}"
                                WidthRequest="200" HeightRequest="200" />




            </Grid>

            <!-- CLOSE ICON -->
            <Label
                Style="{StaticResource IconCloseLabelStyle}">
                <Label.GestureRecognizers>
                    <TapGestureRecognizer
                        Tapped="OnCloseButtonClicked" />
                </Label.GestureRecognizers>
            </Label>

        </Grid>
    </ContentPage.Content>
</ContentPage>

MainActivity.cs

  public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Permission[] grantResults) {
        Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);

        base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
    }

解决此问题的最佳方法是自行处理权限部分

通用权限助手:

using System.Threading.Tasks;
using Xamarin.Essentials;
using static Xamarin.Essentials.Permissions;

public static async Task<PermissionStatus> CheckAndRequestPermissionAsync<TPermission>()
        where TPermission : BasePermission, new()
    {
        TPermission permission = new TPermission();
        var status = await permission.CheckStatusAsync();
        if (status != PermissionStatus.Granted)
        {
            status = await permission.RequestAsync();
        }

        return status;
    }

然后像这样使用它

var status = await PermissionsHelper.CheckAndRequestPermissionAsync<Permissions.Camera>();
if(status != PermissionStatus.Granted)
{
    return;
}