如何将 ZXing.Net.Maui 集成到部分转换的 Xamarin.Android 到 .NET MAUI 项目中以进行 QR/条形码扫描?

问题描述 投票:0回答:1

我正在将 Xamarin.Android 项目转换为 .NET MAUI。该项目是 WebView 的轻量级包装,UI 主要由用 HTML、JavaScript 和 CSS 编写的单独项目处理。该应用程序与本机 Android 功能(例如蓝牙、相机等)进行交互。项目中仅有的两个视图是

InitializationActivity
(用户输入网站的 URL)和
MainActivity
(在 WebView 中显示网站) .

将项目转换为目标 .net8.0-android 后,该应用程序运行良好,除了一项功能:二维码/条形码扫描。在 Xamarin.Android 项目中,我使用了

ZXing.Net.Mobile
库,其中有一个自定义布局,并在 .cs 文件中调用
MobileBarcodeScanner.Scan()
打开相机进行扫描。但是,
ZXing.Net.Mobile
与.NET MAUI不兼容,所以我正在尝试升级到
ZXing.Net.MAUI

ZXing.Net.MAUI
中,似乎我需要一个用于扫描的 MAUI 内容页面,并从我的
MainActivity
导航到该页面。我设法导航到扫描仪页面,但相机没有显示。我也不确定如何将扫描结果发送回我的
MainActivity
,然后发送到我的 WebView,因为这都是 JavaScript 调用。

相关代码如下:

ZXingScannerActivity.cs

[Activity(Label = "ZXingScanActivity")]
public class ZXingScanActivity : Activity
{
    public static string m_Tag = "ZXingScanActivity";
    public static readonly Lazy<MauiApp> MauiApp = new(() =>
    {
        var mauiApp = MauiProgram.CreateMauiApp(builder =>
        {
            builder
                .UseMauiEmbedding()
                .UseBarcodeReader();
        });
        return mauiApp;
    });
    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);
        var mauiApp = MauiApp.Value;
        var mauiContext = new MauiContext(mauiApp.Services, this);
        var mauiView = new ZXingScannerPage();
        var scannerView = mauiView.ToPlatformEmbedded(mauiContext);
        SetContentView(scannerView);
    }
}

MainActivity.cs

public async Task<string> OpenZXingScanner()
{
    RunOnUiThread(() =>
    {
        var intent = new Intent(this, typeof(ZXingScanActivity));
        StartActivity(intent);
    });
    return string.Empty;
}

ZXingScannerPage.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:zxing="clr-namespace:ZXing.Net.Maui.Controls;assembly=ZXing.Net.MAUI.Controls"
             x:Class="TWP.Pages.ZXingScannerPage">

    <zxing:CameraBarcodeReaderView x:Name="barcodeReader" BarcodesDetected="BarcodesDetected" />
</ContentPage>

ZXingScannerPage.xaml.cs

namespace TWP.Pages
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class ZXingScannerPage : ContentPage
    {
        public ZXingScannerPage()
        {
            InitializeComponent();
            barcodeReader.Options = new BarcodeReaderOptions
            {
                Formats = BarcodeFormats.All,
                AutoRotate = true,
                Multiple = false
            };
            barcodeReader.CameraLocation = CameraLocation.Front;
        }

        public void BarcodesDetected(object sender, BarcodeDetectionEventArgs e)
        {
            var first = e.Results?.FirstOrDefault();
            if (first is null)
                return;

            Dispatcher.DispatchAsync(async () =>
            {
                await DisplayAlert("Barcode Detected", first.Value, "OK");
                await Navigation.PopAsync();
            });
        }
    }
}

AndroidManifest.xml

<uses-permission android:name="android.permission.CAMERA" />
android xamarin.android maui zxing zxing.net
1个回答
0
投票

我有一个类似的任务,并遇到了类似的问题:我将一个 xamarin 应用程序移动到了 MAUI 应用程序,并且我在 Xamarin 应用程序上使用 ZXing 实现了 QR 阅读。

虽然这不能完全回答你的问题,但我可以告诉你我是如何解决这个问题的:使用另一个 NuGet 包,即 Camera.MAUI。我花了很多时间尝试使用 ZXing.Net.MAUI,最终放弃了。

MauiProgram.cs

public static MauiApp CreateMauiApp()
{
    var builder = MauiApp.CreateBuilder();
    builder
        .UseMauiApp<App>()
        .ConfigureFonts(fonts =>
        {
            fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
            fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
        })
        .UseMauiCommunityToolkit()
        .UseMauiCameraView();

    return builder.Build();
}

QRScanPage.xaml

<ContentPage
    xmlns:cv="clr-namespace:Camera.MAUI;assembly=Camera.MAUI"
    xmlns:cvz="clr-namespace:Camera.MAUI.ZXingHelper;assembly=Camera.MAUI">

    <cv:CameraView
        x:Name="cameraView"
        BackgroundColor="Transparent"
        IsEnabled="{Binding IsCameraVisible}"
        BarCodeDetectionEnabled="True"
        BarcodeDetected="OnBarcodeDetected"
        Loaded="OnCamerasLoaded">
    </cv:CameraView>
</ContentPage>

QRScanPage.xaml.cs

private void OnCamerasLoaded(object sender, EventArgs e)
{
    if (cameraView.NumCamerasDetected > 0)
    {
        cameraView.Camera = cameraView.Cameras.First();
        cameraView.BarCodeOptions = new BarcodeDecodeOptions
        {
            AutoRotate = true,
            PossibleFormats = { BarcodeFormat.QR_CODE },
            ReadMultipleCodes = false,
            TryHarder = true,
            TryInverted = true
        }; 
        cameraView.BarCodeDetectionFrameRate = 10;
        cameraView.BarCodeDetectionMaxThreads = 5;
        cameraView.ControlBarcodeResultDuplicate = true;

        MainThread.BeginInvokeOnMainThread(async () =>
        {
            await Task.Delay(100);  // Workaround: fixes the initial blurry resolution of the first camera start.
            await cameraView.StartCameraAsync();
        });
    }
}

private void OnBarcodeDetected(object sender, Camera.MAUI.ZXingHelper.BarcodeEventArgs e)
{
    foreach (var result in e.Result)
    {
        if (result.BarcodeFormat == BarcodeFormat.QR_CODE)
        {
           // do stuff
        }
    }
}

您仍然需要相机许可。

希望这有帮助!

编辑:Camera.MAUI 存储库:https://github.com/hjam40/Camera.MAUI

© www.soinside.com 2019 - 2024. All rights reserved.