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
提供了一个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.QrCode 2、安装 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.Dispatch,IDispatcher提供核心事件消息调度程序,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:MasaStackTechOps QQ:7424099

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Glibc 获得 AVX-512 优化,部分函数周期减少约 30%
GNU C 库“glibc”获得另一轮 AVX-512 优化工作,使用英特尔的 AVX-512 处理器或 AMD Zen 4 的用户可从中受益。 AVX-512 是一种 SIMD 指令,用于在执行特定任务时提高 CPU 的性能。英特尔工程师 Sunil K Pandey 为 Glibc 开发了增强型矢量扩展 EVEX512 版本的 memchr、rawmemchr 和 wmemchr 函数,memchr、rawmemchr 和 wmemchr 函数变体用于在内存块中定位字符。 与标准 EVEX 实现相比,这些字符串函数的 EVEX512 版本可减少多达 30% 的函数周期,使用 512 位向量的好处因字符串长度和其他因素而异。 与此同时,今天在 Glibc git 中,Noah Goldstein 对各种 libc 函数的现有 EVEX 实现进行了许多优化。
- 下一篇
Cloud Shuffle Service 在字节跳动 Spark 场景的应用实践
本文整理自字节跳动基础架构的大数据开发工程师魏中佳在 ApacheCon Aisa 2022 「大数据」议题下的演讲,主要介绍 Cloud Shuffle Service(CSS) 在字节跳动 Spark 场景下的设计与实现。 作者|字节跳动基础架构大数据开发工程师-魏中佳 背景介绍 在大数据场景下,数据 Shuffle 表示了不同分区数据交换的过程,Shuffle 的性能往往会成为作业甚至整个集群的性能瓶颈。特别是在字节跳动每日上百 PB Shuffle 数据的场景下,Shuffle 过程暴露出来了很多问题,本文会逐个展开此类问题并介绍在字节跳动的优化实践。 External Shuffle Service 首先来看,在 Spark 3.0 及最新的 Spark 3.3 中,External Shuffle Service(以下简称 ESS)是如何完成 Shuffle 任务的? 如下图,每一个 Map Task,从 Mapper 1 到 Mapper M 都会在本地生成属于自己的 Shuffle 文件。这个 Shuffle 文件内部由 R 个连续的数据片段组成。每一个 Reduce ...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- CentOS关闭SELinux安全模块
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- 2048小游戏-低调大师作品
- SpringBoot2整合Redis,开启缓存,提高访问速度
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- Docker安装Oracle12C,快速搭建Oracle学习环境
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果