You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在.NET MAUI中实现Zebra MC33条码扫描(无需聚焦输入框)

.NET MAUI 适配 Zebra MC33 无输入框条码扫描方案

方案一:基于 Zebra DataWedge 广播接收(推荐,适配原有Xamarin经验)

Zebra DataWedge 通过系统广播传递扫描结果,无需聚焦输入框,MAUI 可直接在 Android 平台层接收广播,再同步到共享项目。

  1. 配置 DataWedge 设备端 Profile

    • 打开设备上的 DataWedge 应用,新建专属 Profile
    • 触发方式选择物理扫描键(符合设备使用习惯)
    • 输出设置选择「Intent」,配置:
      • Action: com.zebra.scanner.SCAN(自定义唯一值,避免冲突)
      • Category: android.intent.category.DEFAULT
  2. MAUI 中实现广播接收器
    在 Android 平台项目中创建广播接收器类,处理扫描数据:

    [BroadcastReceiver(Enabled = true, Exported = true)]
    [IntentFilter(new[] { "com.zebra.scanner.SCAN" }, Categories = new[] { "android.intent.category.DEFAULT" })]
    public class ScanBroadcastReceiver : BroadcastReceiver
    {
        public override void OnReceive(Context? context, Intent? intent)
        {
            if (intent == null || !intent.Action.Equals("com.zebra.scanner.SCAN")) return;
            
            var scanData = intent.GetStringExtra("com.symbol.datawedge.data_string");
            var labelType = intent.GetStringExtra("com.symbol.datawedge.label_type");
            
            // 通过 MessagingCenter 将数据传递到共享项目
            MessagingCenter.Send(this, "ScanReceived", new ScanResult(scanData, labelType));
        }
    }
    
    public class ScanResult
    {
        public string Data { get; }
        public string LabelType { get; }
        public ScanResult(string data, string labelType)
        {
            Data = data;
            LabelType = labelType;
        }
    }
    
  3. 注册/注销广播接收器
    在 Android 项目的 MainActivity 中管理接收器生命周期:

    private ScanBroadcastReceiver? _scanReceiver;
    
    protected override void OnCreate(Bundle? savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        _scanReceiver = new ScanBroadcastReceiver();
        RegisterReceiver(_scanReceiver, new IntentFilter("com.zebra.scanner.SCAN") { AddCategory("android.intent.category.DEFAULT") });
    }
    
    protected override void OnDestroy()
    {
        base.OnDestroy();
        if (_scanReceiver != null)
        {
            UnregisterReceiver(_scanReceiver);
            _scanReceiver = null;
        }
    }
    
  4. 共享项目中处理扫描结果
    在页面或 ViewModel 中订阅广播消息:

    public MainPage()
    {
        InitializeComponent();
        MessagingCenter.Subscribe<ScanBroadcastReceiver, ScanResult>(this, "ScanReceived", (sender, result) =>
        {
            // 主线程更新UI或处理业务逻辑
            MainThread.BeginInvokeOnMainThread(() =>
            {
                ScanResultLabel.Text = $"扫描内容: {result.Data} ({result.LabelType})";
            });
        });
    }
    

方案二:使用 Zebra Scanner SDK 原生调用

如果需要更精细化的扫描控制,可直接集成 Zebra Scanner SDK for Android:

  1. 导入 SDK
    下载 Zebra Scanner SDK for Android 的 AAR 文件,放入 MAUI Android 项目的 libs 文件夹,右键选择「添加为引用」。

  2. 实现扫描服务接口
    共享项目定义接口:

    public interface IScannerService
    {
        event EventHandler<ScanResult> ScanReceived;
        void InitializeScanner();
    }
    

    Android 项目实现接口:

    public class ScannerService : IScannerService
    {
        private IScannerConnection? _scannerConnection;
        public event EventHandler<ScanResult>? ScanReceived;
    
        public void InitializeScanner()
        {
            var scannerManager = ScannerManager.Instance;
            scannerManager.RegisterScannerConnectionListener(new ScannerConnectionListener(this));
            scannerManager.Start();
        }
    
        private class ScannerConnectionListener : Java.Lang.Object, IScannerConnectionListener
        {
            private readonly ScannerService _service;
    
            public ScannerConnectionListener(ScannerService service) => _service = service;
    
            public void OnConnectionEstablished(IScannerConnection connection)
            {
                _service._scannerConnection = connection;
                connection.RegisterScanDataListener(new ScanDataListener(_service));
                connection.Enable();
            }
    
            public void OnConnectionTerminated(IScannerConnection connection) => _service._scannerConnection = null;
            public void OnConnectionTerminatedUnexpectedly(IScannerConnection connection) => _service._scannerConnection = null;
        }
    
        private class ScanDataListener : Java.Lang.Object, IScanDataListener
        {
            private readonly ScannerService _service;
    
            public ScanDataListener(ScannerService service) => _service = service;
    
            public void OnScanDataReceived(IScanDataCollection scanData)
            {
                var item = scanData.GetScanData()[0];
                var result = new ScanResult(item.Data, item.LabelType.Name());
                _service.ScanReceived?.Invoke(_service, result);
            }
        }
    }
    
  3. 注册服务并使用
    在 MauiProgram.cs 中注册依赖服务:

    builder.Services.AddSingleton<IScannerService, ScannerService>();
    

    在页面中注入并初始化:

    private readonly IScannerService _scannerService;
    
    public MainPage(IScannerService scannerService)
    {
        InitializeComponent();
        _scannerService = scannerService;
        _scannerService.ScanReceived += OnScanReceived;
        _scannerService.InitializeScanner();
    }
    
    private void OnScanReceived(object? sender, ScanResult e)
    {
        MainThread.BeginInvokeOnMainThread(() =>
        {
            ScanResultLabel.Text = $"扫描内容: {e.Data} ({e.LabelType})";
        });
    }
    

注意事项

  • Android 权限:需在 AndroidManifest.xml 中添加必要权限,如 ACCESS_FINE_LOCATION(蓝牙扫描场景)、RECEIVE_BOOT_COMPLETED(开机自启需求)
  • 原有 Xamarin 项目迁移失败排查:通常是 MAUI 项目结构配置问题,可将原 Xamarin.Android 中的 DataWedge 相关代码直接复制到 MAUI 的 Android 项目中,调整命名空间和依赖引用即可。

内容的提问来源于stack exchange,提问作者onassik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 05:45:47