写点什么

MASA MAUI Plugin (四)条形码、二维码扫描功能

  • 2022-10-20
    浙江
  • 本文字数:3743 字

    阅读完需:约 1 分钟

背景

MAUI 的出现,赋予了广大.Net 开发者开发多平台应用的能力,MAUI 是 Xamarin.Forms 演变而来,但是相比 Xamarin 性能更好,可扩展性更强,结构更简单。但是 MAUI 对于平台相关的实现并不完整。所以 MASA 团队开展了一个实验性项目,意在对微软 MAUI 的补充和扩展


项目地址https://github.com/BlazorComponent/MASA.Blazor/tree/main/src/Masa.Blazor.Maui.Plugin


每个功能都有单独的 demo 演示项目,考虑到 app 安装文件体积(虽然 MAUI 已经集成裁剪功能,但是该功能对于代码本身有影响),届时每一个功能都会以单独的 nuget 包的形式提供,方便测试,现在项目才刚刚开始,但是相信很快就会有可以交付的内容啦。

前言

本系列文章面向移动开发小白,从零开始进行平台相关功能开发,演示如何参考平台的官方文档使用 MAUI 技术来开发相应功能。

介绍

移动端的扫描条形码、二维码的功能已经随处可见,已经很难找到一个不支持扫描的 App 了,但是微软的 MAUI 竟然没有提供,那么我们应该如何实现呢?


其实早在 Xamarin 开发的时候就已经有前辈实现了扫码功能,例如 ZXing.Net.Mobile ,该包目前依旧可以在 MAUI 的 Android 平台正常工作,但是在 iOS 平台经过测试无法正常工作。


那 iOS 有办法实现扫描条形码功能吗?


前辈已经提供了基于 MAUI 的更新包 ZXing.Net.Maui


https://github.com/Redth/ZXing.Net.Maui


提供了一个 XAML 的控件 zxing:CameraBarcodeReaderView 但是没有提供 Blazor 的组件,因此我们就在此基础上,在 Blazor 中使用 XAML 页面实现条形码扫描功能。

思路

这里我们的思路是在 Blazor 页面通过一个模态弹窗弹出一个新的 XAML 页面,然后在新页面扫码结束后关闭当前页面将扫码结果带回到 Blazor 页面。但是怎么实现呢,我们在 Xamarin.Forms 找到了 INavigation 接口,该接口提供了特定与接口抽象的平台导航,具体参考


https://learn.microsoft.com/en-us/dotnet/api/xamarin.forms.inavigation?view=xamarin-forms


我们可以使用该接口的 PopModalAsync 方法,用来异步弹出一个模态窗口。

开发步骤

1、我们新建一个 MAUI 类库项目 Masa.Blazor.Maui.Plugin.QrCode2、安装 ZXing.Net.MAUI NuGet 包 3、在项目中新建.Net MAUI ContentPage(XAML) BarcodeReader.xaml 文件,并添加如下代码


<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"             x:Class="MauiAppAgent.MasaBarcodeReader"             Title="MasaBarcodeReader">  <VerticalStackLayout>    <zxing:CameraBarcodeReaderView       x:Name="BarcodeReader"      WidthRequest="300"      HeightRequest="300"      IsDetecting="true"       IsTorchOn="false"       BarcodesDetected="CameraBarcodeReaderView_BarcodesDetected"   />    <Button Padding="10" Clicked="ReturnToBlazor_Clicked" Text="返回"></Button>  </VerticalStackLayout></ContentPage>
复制代码


参数说明如下:


WidthRequest HeightRequest:扫描窗口的长宽 IsTorchOn:是否显示手电桶 IsDetecting:是否显示正在检测的界面效果 BarcodesDetected:识别到结果之后的回调方法


在代码文件 BarcodeReader.xaml.cs 中添加代码,实现扫描到结果之后关闭当前模态窗口。另外我们添加了一个按钮方便用户随时退出扫描页面。


public partial class BarcodeReader : ContentPage{    public delegate void BarcodeDetected(string barcodeResult);    public event BarcodeDetected OnBarcodeDetected;    public MasaBarcodeReader()    {        InitializeComponent();        BarcodeReader.Options = new BarcodeReaderOptions        {            Formats = BarcodeFormats.All,            AutoRotate = true,            Multiple = true        };    }    private void CameraBarcodeReaderView_BarcodesDetected(object sender, BarcodeDetectionEventArgs e)    {        Dispatcher.Dispatch(() =>        {            if (OnBarcodeDetected != null)            {                OnBarcodeDetected(e.Results[0].Value);                CloseReader();            }        });    }
private void CloseReader() { Application.Current.MainPage.Navigation.PopModalAsync(true); } private void ReturnToBlazor_Clicked(object sender, EventArgs e) { CloseReader(); }}
复制代码


构造函数中我们指定参数:


BarcodeFormats.OneDimensiona 条码类型,可以是一维条形码(OneDimensiona,支持:Codabar、Code39、Code93、Code128、Ean8、Ean13、Itf、Rss14、RssExpanded、UpcA、UpcE)二维码(TwoDimensional,支持:Aztec 、DataMatrix 、Itf 、MaxiCode 、Pdf417 、QrCode 、UpcEanExtension 、Msi 、Plessey 、Imb)全部 (All,支持以上全部)AutoRotate = True 自动旋转 Multiple = True 可以识别多个条码


CameraBarcodeReaderView_BarcodesDetected 回调方法的 BarcodeDetectionEventArgs 参数为扫描之后的结果,我们可以通过 e.Results,获取扫描到的结果集(因为之前指定了 Multiple = True


这里为了演示我们只取默认的第一个结果作为参数传递给 OnBarcodeDetected 事件,最终将结果传递给 BarcodeDetected


这部分使用了 MAUI 提供的 IDispatcher.DispatchIDispatcher 提供核心事件消息调度程序,Dispatch 方法的参数是一个 Action,该方法将提供的 Action 从一个工作线程安排到 UI 线程运行,如果允许成功就返回 true。


扫描成功后,需要自动关闭当前页面。用户也可以随时通过按钮点击关闭页面。关闭使用 Application.Current.MainPage.Navigation.PopModalAsync(true) 该方法异步关闭最近以模态方式呈现的页面,并带有可选动画。唯一的参数就是是否显示动画效果。


4、我们在根目录添加一个 MasaMauiBarcodeService.cs 静态类


using static Masa.Blazor.Maui.Plugin.QrCode.MasaBarcodeReader;
namespace Masa.Blazor.Maui.Plugin.QrCode{ // All the code in this file is included in all platforms. public static partial class MasaMauiBarcodeService { public static void ReadBarcode(BarcodeDetected actionBarcodeDetected) { MasaBarcodeReader barcodeReaderMauiComponent = new MasaBarcodeReader(); barcodeReaderMauiComponent.OnBarcodeDetected += actionBarcodeDetected; Application.Current.MainPage.Navigation.PushModalAsync(barcodeReaderMauiComponent); } }}
复制代码


INavigation 接口提供了 Application.Current.MainPage.Navigation.PushModalAsync 方法,以模态方式弹出一个窗体/页面,参数就是我们要弹出的窗体的对象也就是我们新建的 MasaBarcodeReader.xaml 页面,我们 new 一个 MasaBarcodeReader 对象,给他的 OnBarcodeDetected 注册传递过来的 actionBarcodeDetected 方法,条形码的扫描结果作为唯一的参数,通过 PushModalAsync 弹出我们的窗口。

使用

我们新建一个 MAUI Blazor 的项目 QrCodeSample 作为演示,我们这里以 iOS 举例,扫码需要摄像头,所以在 Info.plist 添加需要的摄像头权限


  <key>NSCameraUsageDescription</key>  <string>This app uses barcode scanning to...</string>
复制代码


Android 需要在 AndroidManifest.xml 添加摄像头权限,并在使用是动态获取用户授权(本文以 iOS 举例,Android 不做具体实现)


<uses-permission android:name="android.permission.CAMERA" />
复制代码


在 MauiProgram.cs 添加 UseBarcodeReader 初始化方法(这个扩展方法是 ZXing.Net.Maui 提供的)


 var builder = MauiApp.CreateBuilder();            builder                .UseMauiApp<App>()                .UseBarcodeReader() //初始化                ....
复制代码


修改 Index.razor 页面进行测试


@page "/"@using Masa.Blazor.Maui.Plugin.QrCode
<div class="text-center"> <button class="btn btn-warning" @onclick="ReadBarcode">Scan barcodes</button></div>
<div class="mt-3">Barcode: @_barcodeJustRead</div>
@code { private string _barcodeJustRead;
private void ReadBarcode() { MasaMauiBarcodeService.ReadBarcode(BarcodeReaderMauiComponent_OnBarcodeDetected); } private void BarcodeReaderMauiComponent_OnBarcodeDetected(string barcodeResult) { _barcodeJustRead = barcodeResult; StateHasChanged(); }}
复制代码


直接调用 MasaMauiBarcodeService.ReadBarcode 并传递自定义的处理方法 BarcodeReaderMauiComponent_OnBarcodeDetected


我们看一下 iOS 的效果:



扫描效果还是很快很准确的,经过测试 Android 也可以正常使用。


注意:演示项目使用项目名称为 QrCodeSample 短名称,是为了避免 iOS 打包过程中报错,如果文件路径长度超过 255,会报错某些文件无法找到的。



如果你对我们 MASA 感兴趣,无论是代码贡献、使用、提 Issue,欢迎联系我们


WeChat:MasaStackTechOpsQQ:7424099

发布于: 刚刚阅读数: 4
用户头像

还未添加个人签名 2021-10-26 加入

MASA技术团队官方账号,我们专注于.NET现代应用开发解决方案,Wechat:MasaStackTechOps ,Website:www.masastack.com

评论

发布
暂无评论
MASA MAUI Plugin (四)条形码、二维码扫描功能_MASA_MASA技术团队_InfoQ写作社区