Delphi 中接收 Sunmi 和 Unitech 设备广播的实现

欢迎加入全网最大Delphi 技术交流群 682628230

在 Delphi 中开发 Android 应用时,接收来自 Zebra 设备的广播是可行的,但同样的方法在 Sunmi 和 Unitech 设备上却无法正常工作。以下是解决这一问题的核心方法。

 

Zebra 设备的广播可以正常接收,但 Sunmi 和 Unitech 设备的广播无法触发 Delphi 应用中的处理逻辑。日志显示广播已发送,但应用未接收到。

实现方法

1. 使用 BroadcastReceiver

Sunmi 和 Unitech 设备的广播需要通过 BroadcastReceiver 来接收。以下是实现步骤:

定义 TMultiReceiver 类

unit MultiReceiver;

interface

uses
  Androidapi.JNIBridge, Androidapi.JNI.JavaTypes, Androidapi.JNI.GraphicsContentViewText, Androidapi.JNI.Embarcadero;

type
  TMultiReceiver = class;

  TMultiReceiverListener = class(TJavaLocal, JFMXBroadcastReceiverListener)
  private
    FMultiReceiver: TMultiReceiver;
  public
    procedure onReceive(context: JContext; intent: JIntent); cdecl;
  public
    constructor Create(const AMultiReceiver: TMultiReceiver);
  end;

  TIntentEvent = procedure(Sender: TObject; const Intent: JIntent) of object;

  TMultiReceiver = class(TObject)
  private
    FBroadcastReceiver: JFMXBroadcastReceiver;
    FIntentFilter: JIntentFilter;
    FReceiverListener: TMultiReceiverListener;
    FOnIntent: TIntentEvent;
  protected
    procedure Receive(context: JContext; intent: JIntent); virtual;
    procedure ConfigureActions; virtual; abstract;
    property IntentFilter: JIntentFilter read FIntentFilter;
  public
    constructor Create;
    destructor Destroy; override;
    property OnIntent: TIntentEvent read FOnIntent write FOnIntent;
  end;

implementation

uses
  Androidapi.Helpers;

{ TMultiReceiverListener }

constructor TMultiReceiverListener.Create(const AMultiReceiver: TMultiReceiver);
begin
  inherited Create;
  FMultiReceiver := AMultiReceiver;
end;

procedure TMultiReceiverListener.onReceive(context: JContext; intent: JIntent);
begin
  FMultiReceiver.Receive(context, intent);
end;

{ TMultiReceiver }

constructor TMultiReceiver.Create;
begin
  inherited Create;
  FReceiverListener := TMultiReceiverListener.Create(Self);
  FBroadcastReceiver := TJFMXBroadcastReceiver.JavaClass.init(FReceiverListener);
  FIntentFilter := TJIntentFilter.JavaClass.init;
  ConfigureActions;
  TAndroidHelper.Context.registerReceiver(FBroadcastReceiver, FIntentFilter);
end;

destructor TMultiReceiver.Destroy;
begin
  TAndroidHelper.Context.unregisterReceiver(FBroadcastReceiver);
end;

procedure TMultiReceiver.Receive(context: JContext; intent: JIntent);
begin
  if Assigned(FOnIntent) then
    FOnIntent(Self, intent);
end;

end.

使用 TMultiReceiver 接收广播

unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
  Androidapi.JNI.GraphicsContentViewText, Androidapi.JNI.JavaTypes,
  MultiReceiver;

type
  TScannerReceiver = class(TMultiReceiver)
  protected
    procedure ConfigureActions; override;
  end;

  TForm1 = class(TForm)
  private
    FScannerReceiver: TScannerReceiver;
    procedure ScannerReceiverIntentHandler(Sender: TObject; const AIntent: JIntent);
  public
    constructor Create(AOwner: TComponent); override;
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

uses
  Androidapi.Helpers;

const
  cActionSunmi = 'com.sunmi.scanner.ACTION_DATA_CODE_RECEIVED';
  cActionUnitech = 'unitech.scanservice.data';

{ TScannerReceiver }

procedure TScannerReceiver.ConfigureActions;
begin
  IntentFilter.addAction(StringToJString(cActionSunmi));
  IntentFilter.addAction(StringToJString(cActionUnitech));
end;

{ TForm1 }

constructor TForm1.Create(AOwner: TComponent);
begin
  inherited;
  FScannerReceiver := TScannerReceiver.Create;
  FScannerReceiver.OnIntent := ScannerReceiverIntentHandler;
end;

procedure TForm1.ScannerReceiverIntentHandler(Sender: TObject; const AIntent: JIntent);
begin
  if AIntent.getAction.Equals(StringToJString(cActionSunmi)) then
  begin
    // 处理 Sunmi 广播
  end
  else if AIntent.getAction.Equals(StringToJString(cActionUnitech)) then
  begin
    // 处理 Unitech 广播
  end;
end;

end.

2. 关键点

  • 广播接收器:Sunmi 和 Unitech 设备的广播需要通过 BroadcastReceiver 接收,而不是 registerIntentAction

  • IntentFilter:在 ConfigureActions 方法中添加需要接收的广播动作。

  • 处理广播:在 ScannerReceiverIntentHandler 中根据广播动作处理数据。

3. 注意事项

  • 确保 AndroidManifest.xml 中已正确配置 <intent-filter>

  • 如果使用 registerIntentAction,只能接收通过 startActivity 发送的 Intent,无法接收广播。

通过以上方法,可以成功接收 Sunmi 和 Unitech 设备的广播,并处理相关数据。

© 版权声明
THE END
喜欢就支持一下吧
点赞12 分享