在 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