0

I am in the process of converting a Xamarin.Android project to .NET MAUI. The project is a lightweight wrapper around a WebView, with the UI primarily being handled by a separate project written in HTML, JavaScript, and CSS. The app interacts with native Android features such as Bluetooth, camera, etc. The only two views in the project are InitializationActivity (where the user enters the URL of the website) and MainActivity (which displays the website in a WebView).

After converting the project to target .net8.0-android, the app works fine except for one feature: QR/Barcode scanning. In the Xamarin.Android project, I used the ZXing.Net.Mobile library, where I had a custom layout, and called MobileBarcodeScanner.Scan() in my .cs file to open the camera for scanning. However, ZXing.Net.Mobile is incompatible with .NET MAUI, so I am trying to upgrade to ZXing.Net.MAUI.

In ZXing.Net.MAUI, it seems I need to have a MAUI content page for the scan and navigate to that page from my MainActivity. I managed to navigate to the scanner page, but the camera is not showing up. I am also unsure how to send the scan result back to my MainActivity and then to my WebView, as it is all a JavaScript call.

Here is the relevant code:

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" />

1 Answer 1

0

I had a similar task, and fell on a similar problem: I moved a xamarin app to a MAUI one, and I had implemented QR Reading using ZXing on the Xamarin app.

Albeit this won't exactly answer your question, I can tell you how I got around the problem : using another NuGet Package which is Camera.MAUI. I spent so much time trying to use ZXing.Net.MAUI and eventually just gave up.

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
        }
    }
}

You'll still need the camera permission.

Hope this helps !

Edit: Camera.MAUI repo : https://github.com/hjam40/Camera.MAUI

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, @5coJL! I tried Camera.MAUI. However, I have the same problem. My problem is that my project does not even have MauiProgram.cs. As I converted my Xamarin.Android to .NET MAUI, I still only have old-style activities like MainActivity.cs where I have native embedded MAUI content page for ZXing scanning. This takes me to the ZXing scanning content page but my camera is not showing up. I only got a blank screen. Please find my GitHub repo with minimal files required to reproduce my issue: github.com/nandhakishore92/ZXingMauiNativeEmbedding. If you could help me, it will be great.
Were you able to resolve your issue?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.