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

.NET MAUI Android平台扫描DataMatrix码如何读取隐藏字符(如char(29))

在.NET MAUI Android平台读取DataMatrix码中隐藏字符的解决方案

问题原因

MAUI的Entry控件在Android平台默认会过滤不可见的控制字符(如char(29)即分组分隔符\u001D),直接通过Entry.Text无法获取这类字符。而Windows平台的PreviewTextInput事件可以直接捕获控制字符,两者的输入处理逻辑不同。

解决方案:自定义Entry的Android平台渲染器

通过自定义渲染器对接Android原生EditText,绕过MAUI的字符过滤逻辑,直接捕获所有输入字符(包括控制字符)。

步骤1:创建共享项目的自定义Entry控件

public class ScanEntry : Entry
{
    // 定义事件传递原始输入文本(含控制字符)
    public event EventHandler<string> RawTextReceived;
    
    internal void RaiseRawTextReceived(string rawText)
    {
        RawTextReceived?.Invoke(this, rawText);
    }
}

步骤2:实现Android平台的自定义渲染器

在Android项目中添加渲染器,对接原生EditText并监听文本变化:

[assembly: ExportRenderer(typeof(ScanEntry), typeof(ScanEntryRenderer))]
namespace YourAppNamespace.Platforms.Android
{
    public class ScanEntryRenderer : EntryRenderer
    {
        private ScanEntry _scanEntry;
        private EditText _nativeEditText;

        public ScanEntryRenderer(Context context) : base(context)
        {
        }

        protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
        {
            base.OnElementChanged(e);

            if (e.OldElement != null)
            {
                // 清理旧监听
                _nativeEditText?.RemoveTextChangedListener(_textWatcher);
            }

            if (e.NewElement is ScanEntry scanEntry)
            {
                _scanEntry = scanEntry;
                _nativeEditText = Control as EditText;

                // 移除默认的字符过滤规则,允许所有字符(含控制字符)
                _nativeEditText.SetFilters(new IInputFilter[0]);

                // 添加文本监听捕获原始输入
                var textWatcher = new ScanTextWatcher(scanEntry);
                _nativeEditText.AddTextChangedListener(textWatcher);
            }
        }

        // 自定义TextWatcher捕获原生文本
        private class ScanTextWatcher : Java.Lang.Object, ITextWatcher
        {
            private readonly ScanEntry _scanEntry;

            public ScanTextWatcher(ScanEntry scanEntry)
            {
                _scanEntry = scanEntry;
            }

            public void AfterTextChanged(IEditable s)
            {
                // 获取含控制字符的原始文本并传递到共享项目
                string rawText = s.ToString();
                _scanEntry.RaiseRawTextReceived(rawText);
            }

            public void BeforeTextChanged(ICharSequence s, int start, int count, int after) { }
            public void OnTextChanged(ICharSequence s, int start, int before, int count) { }
        }
    }
}

步骤3:在MAUI页面中使用自定义Entry

在XAML中引用自定义控件并绑定事件:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:YourAppNamespace"
             x:Class="YourAppNamespace.ScanPage">
    <StackLayout>
        <local:ScanEntry RawTextReceived="ScanEntry_RawTextReceived" />
    </StackLayout>
</ContentPage>

步骤4:处理原始输入文本

在页面后台代码中接收含控制字符的原始数据:

private void ScanEntry_RawTextReceived(object sender, string rawText)
{
    SCANTXT = rawText.Replace("\u001D", "[GS]");
    SCANTXTRAW = rawText;

    Console.WriteLine($"SCANTXT: {SCANTXT}");
    Console.WriteLine($"SCANTXTRAW: {SCANTXTRAW}");

    // 这里添加扫描完成后的业务逻辑
}

额外说明

  • 如果扫描设备是通过蓝牙串口而非模拟键盘输入数据,需使用对应串口通信库直接读取数据,无需依赖Entry控件。
  • 该方案通过原生控件绕过MAUI的字符过滤,确保能完整捕获DataMatrix码中的所有隐藏控制字符。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 07:38:15