ScanService.cs 4.2 KB
using System;
using Microsoft.Maui.Controls;

#if ANDROID
using Android.Content;
using Android.Util;   // ✅ 用于 Log
using IndustrialControl.Droid; // 需要 DynamicScanReceiver
#endif

namespace IndustrialControl.Services
{
    public class ScanService
    {
        public event Action<string, string>? Scanned;

        public string? Prefix { get; set; }
        public string? Suffix { get; set; }
        public int DebounceMs { get; set; } = 250;

        private string? _lastData;
        private DateTime _lastAt = DateTime.MinValue;

        public const string BroadcastAction = "lc";
        public const string DataKey = "data";
        public const string TypeKey = "SCAN_BARCODE_TYPE_NAME";

        public void Attach(Entry entry)
        {
            entry.Completed += (s, e) =>
            {
                var data = entry.Text?.Trim();
                if (!string.IsNullOrEmpty(data))
                {
#if ANDROID
                    Log.Info("ScanService", $"[Attach] Entry.Completed -> {data}");
#endif
                    Scanned?.Invoke(data, "kbd");
                    entry.Text = string.Empty;
                }
            };

            entry.TextChanged += (s, e) =>
            {
                if (string.IsNullOrEmpty(e.NewTextValue)) return;

                if (e.NewTextValue.EndsWith("\n") || e.NewTextValue.EndsWith("\r"))
                {
                    var data = e.NewTextValue.Trim();
#if ANDROID
                    Log.Info("ScanService", $"[Attach] Entry.TextChanged -> {data}");
#endif
                    Scanned?.Invoke(data, "kbd");
                    entry.Text = string.Empty;
                }
            };
        }

        public void Publish(string code, string type = "")
        {
#if ANDROID
            Log.Info("ScanService", $"[Publish] 模拟扫码 -> {code}, type={type}");
#endif
            FilterAndRaise(code, type);
        }

        public void StartListening()
        {
#if ANDROID
  Android.Util.Log.Info("ScanService", "[StartListening] ENTER");
            if (_receiver != null) return;

            _receiver = new DynamicScanReceiver();
            _receiver.OnScanned += OnScannedFromPlatform;

            _filter = new IntentFilter(BroadcastAction);
            Android.App.Application.Context.RegisterReceiver(_receiver, _filter);

            Log.Info("ScanService", $"[StartListening] 已注册广播 Action={BroadcastAction}");
#endif
        }

        public void StopListening()
        {
#if ANDROID
            if (_receiver == null) return;

            try
            {
                Android.App.Application.Context.UnregisterReceiver(_receiver);
                Log.Info("ScanService", "[StopListening] 已注销广播");
            }
            catch (Exception ex)
            {
                Log.Warn("ScanService", $"[StopListening] 注销异常: {ex.Message}");
            }

            _receiver.OnScanned -= OnScannedFromPlatform;
            _receiver = null;
            _filter = null;
#endif
        }

        private bool FilterAndRaise(string data, string type)
        {
            if (!string.IsNullOrEmpty(Prefix) && data.StartsWith(Prefix))
                data = data.Substring(Prefix.Length);

            if (!string.IsNullOrEmpty(Suffix) && data.EndsWith(Suffix))
                data = data.Substring(0, data.Length - Suffix.Length);

            var now = DateTime.UtcNow;
            if (_lastData == data && (now - _lastAt).TotalMilliseconds < DebounceMs)
            {
#if ANDROID
                Log.Info("ScanService", $"[FilterAndRaise] 数据去抖: {data}");
#endif
                return false;
            }

            _lastData = data;
            _lastAt = now;

#if ANDROID
            Log.Info("ScanService", $"[FilterAndRaise] 最终触发 -> {data}, type={type}");
#endif
            Scanned?.Invoke(data, type);
            return true;
        }

#if ANDROID
        private DynamicScanReceiver? _receiver;
        private IntentFilter? _filter;

        private void OnScannedFromPlatform(string data, string type)
        {
            Log.Info("ScanService", $"[OnScannedFromPlatform] 原始数据 -> {data}, type={type}");
            FilterAndRaise(data, type);
        }
#endif
    }
}