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;
}
我在 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;
}