How to Build a .NET MAUI Barcode and QR Code Reader for Windows and Android

.NET MAUI is a cross-platform framework that allows developers to create desktop and mobile applications from a single codebase with C#. It is currently in preview and the production release is slated for Q2 2022. This article goes through the steps to build a .NET MAUI barcode and QR code reader app for Windows and Android using Dynamsoft Barcode Reader SDK.

Dev Environment

  • Visual Studio 2022 Preview

    You need to upgrade Visual Studio to 2022 Preview in order to get the MAUI template.

Steps to Build Barcode and QR Code Reader in .NET MAUI

In the following paragraphs, we make a .NET MAUI app from scratch. You will see how to install different dependencies, as well as how to define cross-platform API for Windows and Android.

Step 1: Create a .NET MAUI Project

In project creation dialog, we enter maui in the search box or select MAUI from All project types to quickly find the MAUI templates.

create maui project

By default, the template generates a project skeleton for Windows, Android, iOS, macOS and Tizen. We clean up the project by removing relevant code and configurations of iOS, macOS and Tizen.

Step 2: Install Dependencies Respectively for Windows and Android

Launch NuGet Package Manager to install Barcode and QR Code SDK:

Since the dependent packages are platform-specific, they must be conditionally correlated to each platform. After installing NuGet packages automatically, you need to manually editing following items in *.csproj file to avoid build errors:

<ItemGroup Condition="'$(TargetFramework)' == 'net6.0-android'">
<PackageReference Include="Xamarin.Dynamsoft.Barcode.Android">
    <Version>9.0.0</Version>
</PackageReference>
</ItemGroup>

<ItemGroup Condition="$(TargetFramework.Contains('-windows')) == true ">
    <PackageReference Include="BarcodeQRCodeSDK" Version="1.2.1" />
</ItemGroup>

Step3: Define the Cross-platform API

According to the official tutorial - Invoke platform code, we define a partial class named BarcodeQRCodeService.cs in the Services folder:

namespace BarcodeQRCode.Services
{
    public partial class BarcodeQRCodeService
    {
        public partial void InitSDK(string license);
        public partial string DecodeFile(string filePath);
    }
}

Then create BarcodeQRCodeService.cs files respectively in Windows and Android folders to implement the API:

MAUI cross-platform API

Android

using BarcodeQRCode.Platforms.Android;
using Com.Dynamsoft.Dbr;

namespace BarcodeQRCode.Services
{
    public partial class BarcodeQRCodeService
    {
        BarcodeReader reader;

        public partial void InitSDK(string license)
        {
            BarcodeReader.InitLicense(license, new DBRLicenseVerificationListener());
            reader = new BarcodeReader();
        }

        public partial string DecodeFile(string filePath)
        {
            string decodingResult = "";

            try
            {

                TextResult[] results = reader.DecodeFile(filePath);
                if (results != null)
                {
                    foreach (TextResult result in results)
                    {
                        decodingResult += result.BarcodeText + "\n";
                    }
                }
                else
                {
                    decodingResult = "No barcode found.";
                }
            }
            catch (Exception e)
            {
                decodingResult = e.Message;
            }
            
            return decodingResult;
        }
    }
}

Windows

using Dynamsoft;

namespace BarcodeQRCode.Services
{
    public partial class BarcodeQRCodeService
    {
        BarcodeQRCodeReader? reader = null;
        
        public partial void InitSDK(string license)
        {
            BarcodeQRCodeReader.InitLicense(license); 

            try
            {
                reader = BarcodeQRCodeReader.Create();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }

        public partial string DecodeFile(string filePath)
        {
            if (reader == null)
                return "";

            string decodingResult = "";            
            try
            {
                string[]? results = reader.DecodeFile(filePath);
                if (results != null)
                {
                    foreach (string result in results)
                    {
                        decodingResult += result + "\n";
                    }
                }
                else
                {
                    decodingResult = "No barcode found.";
                }
            }
            catch (Exception e)
            {
                decodingResult = e.Message;
            }

            return decodingResult;
        }
    }
}

For Android, in addition to the above, we also need to create a DBRLicenseVerificationListener.cs file to implement the interface IDBRLicenseVerificationListener:

using Com.Dynamsoft.Dbr;

namespace BarcodeQRCode.Platforms.Android
{
    public class DBRLicenseVerificationListener : Java.Lang.Object, IDBRLicenseVerificationListener
    {
        public void DBRLicenseVerificationCallback(bool isSuccess, Java.Lang.Exception error)
        {
            if (!isSuccess)
            {
                System.Console.WriteLine(error.Message);
            }
        }
    }

}

Step 4: Add UI Elements

We use MAUI template to create a new content page named ReaderPage.xaml:

MAUI content page

The page contains a label for displaying barcode and QR code decoding results, a button for loading an image file, and a image for showing the image:

<?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"
                x:Class="BarcodeQRCode.ReaderPage"
                Title="ReaderPage">
    <ScrollView>
        <VerticalStackLayout>
            <Button 
                Text="Select a file"
                FontAttributes="Bold"
                SemanticProperties.Hint="Decode barcode and QR code from the file"
                Clicked="OnFilePickerClicked"
                HorizontalOptions="Center" />
            <Label 
                FontSize="18"
                FontAttributes="Bold"
                x:Name="ResultLabel"
                HorizontalOptions="Center" />
            <Image
                x:Name="Image"
                SemanticProperties.Description="Decode barcode and QR code from the image file"
                WidthRequest="640"
                HeightRequest="640"
                HorizontalOptions="Center" />
        </VerticalStackLayout>
    </ScrollView>
</ContentPage>

Apply for a 30-day trial license and then switch to the corresponding ReaderPage.xaml.cs file to add file picking and image decoding logic:

namespace BarcodeQRCode;

using BarcodeQRCode.Services;

public partial class ReaderPage : ContentPage
{
    BarcodeQRCodeService _barcodeQRCodeService;

    public ReaderPage()
    {
        InitializeComponent();

        InitService();
    }

    private async void InitService()
    {
        await Task.Run(() =>
        {
            _barcodeQRCodeService = new BarcodeQRCodeService();

            try
            {
                _barcodeQRCodeService.InitSDK("DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTE2NDk4Mjk3OTI2MzUiLCJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSIsInNlc3Npb25QYXNzd29yZCI6IndTcGR6Vm05WDJrcEQ5YUoifQ==");
            }
            catch (Exception ex)
            {
                DisplayAlert("Error", ex.Message, "OK");
            }

            return Task.CompletedTask;
        });
    }

    private async void OnFilePickerClicked(object sender, EventArgs e)
    {
        FileResult file;
        try
        {
            file = await FilePicker.PickAsync(PickOptions.Images);

            if (file == null) return;

            FileLabel.Text = $"File picked: {file.FileName}";

            Image.Source = ImageSource.FromFile(file.FullPath);

            var result = _barcodeQRCodeService.DecodeFile(file.FullPath);
            ResultLabel.Text = result;
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }
}

So far, the ReaderPage is done. We can add a button in MainPage.xaml to navigate to the ReaderPage:

<Button 
Text="Barcode/QR Code Reader"
FontAttributes="Bold"
SemanticProperties.Hint="Counts the number of times you click"
Clicked="OnReaderClicked"
HorizontalOptions="Center" />
private void OnReaderClicked(object sender, EventArgs e)
{
    Navigation.PushAsync(new ReaderPage());
}

Finally, select a framework and build the project.

  • Android

    MAUI Android

  • Windows

    MAUI Windows

    MAUI barcode and QR code reader

Source Code

https://github.com/yushulx/dotnet-maui-barcode-qrcode-reader