2using CommunityToolkit.Maui.Layouts;
4using CommunityToolkit.Mvvm.Messaging;
5using Microsoft.Maui.Controls.PlatformConfiguration;
6using Microsoft.Maui.Controls.PlatformConfiguration.iOSSpecific;
10using Android.Graphics;
11using AndroidX.Camera.Core;
12using AndroidX.Camera.Core.Impl;
14using System.Reflection;
15using ZXing.Net.Maui.Controls;
16using ZXing.Net.Maui.Readers;
30 this.BindingContext = vm;
32 this.InitializeComponent();
35 this.LinkEntry.Keyboard = Keyboard.Url;
36 this.LinkEntry.IsSpellCheckEnabled =
false;
37 this.LinkEntry.IsTextPredictionEnabled =
false;
39 StateContainer.SetCurrentState(this.GridWithAnimation,
"AutomaticScan");
41 this.CameraBarcodeReaderView.IsDetecting =
false;
42 this.CameraBarcodeReaderView.Options =
new BarcodeReaderOptions
44 Formats = BarcodeFormats.TwoDimensional,
51 vm.DoSwitchMode(
true);
59 await base.OnAppearingAsync();
64 this.ApplyState(vm.IsAutomaticScan, initial:
true);
65 this.CameraBarcodeReaderView.IsTorchOn = vm.IsTorchOn;
66 this.CameraBarcodeReaderView.CameraLocation = vm.CameraLocation;
67 vm.PropertyChanged += this.VmOnPropertyChanged;
75 vm.PropertyChanged -= this.VmOnPropertyChanged;
76 await MainThread.InvokeOnMainThreadAsync(this.CloseCamera);
77 await base.OnDisappearingAsync();
80 private async
void VmOnPropertyChanged(
object? sender,
System.ComponentModel.PropertyChangedEventArgs e)
85 switch (e.PropertyName)
88 await this.Dispatcher.DispatchAsync(() => this.ApplyState(vm.IsAutomaticScan));
91 this.CameraBarcodeReaderView.IsTorchOn = vm.IsTorchOn;
94 this.CameraBarcodeReaderView.IsDetecting = vm.IsDetecting;
97 this.CameraBarcodeReaderView.CameraLocation = vm.CameraLocation;
102 private async
void ApplyState(
bool isAutomatic,
bool initial =
false)
106 string current = StateContainer.GetCurrentState(this.GridWithAnimation);
107 bool currentlyAutomatic =
string.Equals(current,
"AutomaticScan", StringComparison.OrdinalIgnoreCase);
108 if (currentlyAutomatic == isAutomatic && !initial)
116 if (!currentlyAutomatic)
117 StateContainer.SetCurrentState(this.GridWithAnimation,
"AutomaticScan");
118 this.LinkEntry.Unfocus();
120 await Task.Delay(250);
121 this.CameraBarcodeReaderView.IsDetecting =
true;
125 StateContainer.SetCurrentState(this.GridWithAnimation,
"ManualScan");
126 this.CameraBarcodeReaderView.IsTorchOn =
false;
127 this.CameraBarcodeReaderView.IsDetecting =
false;
128 this.LinkEntry.Focus();
136 this.CameraBarcodeReaderView.IsTorchOn =
false;
137 this.CameraBarcodeReaderView.IsDetecting =
false;
138 await StateContainer.ChangeStateWithAnimation(this.GridWithAnimation,
"ManualScan", CancellationToken.None);
139 this.LinkEntry.Focus();
143 this.LinkEntry.Unfocus();
145 if (this.CameraBarcodeReaderView.CameraLocation == CameraLocation.Rear)
147 this.CameraBarcodeReaderView.CameraLocation = CameraLocation.Front;
148 this.CameraBarcodeReaderView.CameraLocation = CameraLocation.Rear;
152 this.CameraBarcodeReaderView.CameraLocation = CameraLocation.Rear;
153 this.CameraBarcodeReaderView.CameraLocation = CameraLocation.Front;
155 await StateContainer.ChangeStateWithAnimation(this.GridWithAnimation,
"AutomaticScan", CancellationToken.None);
156 this.CameraBarcodeReaderView.IsDetecting =
true;
179 this.CameraBarcodeReaderView.IsDetecting =
false;
181 ICameraInternal? preview = await GetCameraPreview(this.CameraBarcodeReaderView);
190 return Task.CompletedTask;
200 private static async Task<ICameraInternal?> GetCameraPreview(CameraBarcodeReaderView cameraBarcodeReaderView)
203 PermissionStatus status = await Permissions.CheckStatusAsync<Permissions.Camera>();
204 if (status == PermissionStatus.Denied)
207 BindingFlags BindingFlags = BindingFlags.NonPublic | BindingFlags.Instance;
208 PropertyInfo? StrongHandlerProperty = typeof(CameraBarcodeReaderView).GetProperty(
"StrongHandler", BindingFlags);
209 CameraBarcodeReaderViewHandler? CameraBarcodeReaderViewHandler = StrongHandlerProperty?.GetValue(cameraBarcodeReaderView) as CameraBarcodeReaderViewHandler;
210 FieldInfo? ManageField = typeof(CameraBarcodeReaderViewHandler).GetField(
"cameraManager", BindingFlags);
211 object? CameraManager = ManageField?.GetValue(CameraBarcodeReaderViewHandler);
212 FieldInfo? CameraPreviewField = typeof(CameraBarcodeReaderViewHandler).Assembly.GetType(
"ZXing.Net.Maui.CameraManager")?.GetField(
"cameraPreview", BindingFlags);
213 Preview? Preview = CameraPreviewField?.GetValue(CameraManager) as Preview;
215 return Preview?.Camera;
220 private async
void CameraBarcodeReaderView_BarcodesDetected(
object sender, BarcodeDetectionEventArgs e)
222 string? Result = (e.Results.Length > 0) ? e.Results[0].Value :
null;
224 await
this.Dispatcher.DispatchAsync(async () =>
226 ScanQrCodeViewModel ViewModel = this.ViewModel<ScanQrCodeViewModel>();
227 await ViewModel.SetScannedText(Result);
Base class that references services in the app.
static ILogService LogService
Log service.
A page to display for scanning of a QR code, either automatically via the camera, or by entering the ...
override async Task OnAppearingAsync()
override async Task OnDisappearingAsync()
The view model to bind to when scanning a QR code.