MASA MAUI Plugin (四)条形码、二维码扫描功能
背景
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 文件,并添加如下代码
参数说明如下:
WidthRequest 和 HeightRequest:扫描窗口的长宽 IsTorchOn:是否显示手电桶 IsDetecting:是否显示正在检测的界面效果 BarcodesDetected:识别到结果之后的回调方法
在代码文件 BarcodeReader.xaml.cs 中添加代码,实现扫描到结果之后关闭当前模态窗口。另外我们添加了一个按钮方便用户随时退出扫描页面。
构造函数中我们指定参数:
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.Dispatch,IDispatcher 提供核心事件消息调度程序,Dispatch 方法的参数是一个 Action,该方法将提供的 Action 从一个工作线程安排到 UI 线程运行,如果允许成功就返回 true。
扫描成功后,需要自动关闭当前页面。用户也可以随时通过按钮点击关闭页面。关闭使用 Application.Current.MainPage.Navigation.PopModalAsync(true) 该方法异步关闭最近以模态方式呈现的页面,并带有可选动画。唯一的参数就是是否显示动画效果。
4、我们在根目录添加一个 MasaMauiBarcodeService.cs 静态类
INavigation 接口提供了 Application.Current.MainPage.Navigation.PushModalAsync 方法,以模态方式弹出一个窗体/页面,参数就是我们要弹出的窗体的对象也就是我们新建的 MasaBarcodeReader.xaml 页面,我们 new 一个 MasaBarcodeReader 对象,给他的 OnBarcodeDetected 注册传递过来的 actionBarcodeDetected 方法,条形码的扫描结果作为唯一的参数,通过 PushModalAsync 弹出我们的窗口。
使用
我们新建一个 MAUI Blazor 的项目 QrCodeSample 作为演示,我们这里以 iOS 举例,扫码需要摄像头,所以在 Info.plist 添加需要的摄像头权限
Android 需要在 AndroidManifest.xml 添加摄像头权限,并在使用是动态获取用户授权(本文以 iOS 举例,Android 不做具体实现)
在 MauiProgram.cs 添加 UseBarcodeReader 初始化方法(这个扩展方法是 ZXing.Net.Maui 提供的)
修改 Index.razor 页面进行测试
直接调用 MasaMauiBarcodeService.ReadBarcode 并传递自定义的处理方法 BarcodeReaderMauiComponent_OnBarcodeDetected
我们看一下 iOS 的效果:
扫描效果还是很快很准确的,经过测试 Android 也可以正常使用。
注意:演示项目使用项目名称为 QrCodeSample 短名称,是为了避免 iOS 打包过程中报错,如果文件路径长度超过 255,会报错某些文件无法找到的。
如果你对我们 MASA 感兴趣,无论是代码贡献、使用、提 Issue,欢迎联系我们
WeChat:MasaStackTechOpsQQ:7424099
版权声明: 本文为 InfoQ 作者【MASA技术团队】的原创文章。
原文链接:【http://xie.infoq.cn/article/f4c5c4901dc1d8b9bfe700658】。文章转载请联系作者。
评论