Delphi 10.3 Android 意图广播接收器
Delphi 10.3 Android Intent BroadcastReceiver
我有一个 ZEBRA TC20,我已经根据本指南配置了 DataWedge:
https://techdocs.zebra.com/datawedge/6-6/guide/api/tutorials/
我做的唯一不同是 Intent Action:com.xlr.ACTION
在 Delphi 中,我有以下单元来处理这个(从 Embarcadero 找到示例):
unit uScanner;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, System.Messaging, FMX.Platform,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, Androidapi.JNI.GraphicsContentViewText,
FMX.Controls.Presentation, FMX.StdCtrls, FMX.Layouts, FMX.WebBrowser, FMX.Objects, FMX.ScrollBox, FMX.Memo;
type
TScanner = class(TForm)
Memo1: TMemo;
Label1: TLabel;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
function HandleAppEvent(AAppEvent: TApplicationEvent; Acontext: TObject) : Boolean;
procedure HandleActivityMessage(const Sender: TObject; const M: TMessage);
function HandleIntentAction(const Data: JIntent): Boolean;
public
{ Public declarations }
end;
var
Scanner: TScanner;
implementation
{$R *.fmx}
uses FMX.Platform.Android, Androidapi.JNI.JavaTypes, Androidapi.JNI.Net, Androidapi.JNI.Os, Androidapi.Helpers;
procedure TScanner.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := TCloseAction.caFree;
end;
procedure TScanner.FormCreate(Sender: TObject);
var
AppEventService : IFMXApplicationEventService;
begin
if TPlatformServices.Current.SupportsPlatformService(IFMXApplicationEventService, AppEventService) then
AppEventService.SetApplicationEventHandler(HandleAppEvent);
MainActivity.registerIntentAction(StringToJString('com.xlr.ACTION'));
TMessageManager.DefaultManager.SubscribeToMessage(TMessageReceivedNotification, HandleActivityMessage);
end;
procedure TScanner.HandleActivityMessage(const Sender: TObject; const M: TMessageBase);
begin
if M is TMessageReceivedNotification then
HandleIntentAction(TMessageReceivedNotification(M).Value);
end;
function TScanner.HandleAppEvent(AAppEvent: TApplicationEvent; Acontext: TObject): Boolean;
var
StartupIntent: JIntent;
begin
Result := False;
if AAppEvent = TApplicationEvent.BecameActive then
begin
StartupIntent := MainActivity.getIntent;
if StartupIntent <> nil then
HandleIntentACtion(StartupIntent);
end;
end;
function TScanner.HandleIntentAction(const Data: JIntent): Boolean;
var
Extras: JBundle;
begin
Result := False;
if Data <> nil then
begin
Extras := Data.getExtras;
if Extras <> nil then
Label1.Text:=JStringToString(Extras.GetString(StringToJString('com.symbol.datawedge.data_string')));
end;
end;
end.
我也修改了AndroidManifest.template.xml
,变成这样:
<?xml version="1.0" encoding="utf-8"?>
<!-- BEGIN_INCLUDE(manifest) -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="%package%"
android:versionCode="%versionCode%"
android:versionName="%versionName%"
android:installLocation="%installLocation%">
<uses-sdk android:minSdkVersion="%minSdkVersion%" android:targetSdkVersion="%targetSdkVersion%" />
<%uses-permission%>
<uses-feature android:glEsVersion="0x00020000" android:required="True"/>
<application android:persistent="%persistent%"
android:restoreAnyVersion="%restoreAnyVersion%"
android:label="%label%"
android:debuggable="%debuggable%"
android:largeHeap="%largeHeap%"
android:icon="%icon%"
android:theme="%theme%"
android:hardwareAccelerated="%hardwareAccelerated%"
android:resizeableActivity="false">
<%provider%>
<%application-meta-data%>
<%uses-libraries%>
<%services%>
<!-- Our activity is a subclass of the built-in NativeActivity framework class.
This will take care of integrating with our NDK code. -->
<activity android:name="com.embarcadero.firemonkey.FMXNativeActivity"
android:label="%activityLabel%"
android:configChanges="orientation|keyboard|keyboardHidden|screenSize"
android:launchMode="singleTask">
<!-- Tell NativeActivity the name of our .so -->
<meta-data android:name="android.app.lib_name"
android:value="%libNameValue%" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="com.xlr.ACTION" />
<category android:name="" />
</intent-filter>
</activity>
<%activity%>
<%receivers%>
</application>
</manifest>
<!-- END_INCLUDE(manifest) -->
我已经在调试模式下启动了应用程序,并在 HandleActivityMessage
处设置了一个断点,但没有任何反应。
有人可以帮我一下吗?
procedure TForm1.FormCreate(Sender: TObject);
var
AppEventService: IFMXApplicationEventService;
begin
if TPlatformServices.Current.SupportsPlatformService(IFMXApplicationEventService, AppEventService) then
AppEventService.SetApplicationEventHandler(HandleAppEvent);
// Register the type of intent action that we want to be able to receive.
// Note: A corresponding <action> tag must also exist in the <intent-filter> section of AndroidManifest.template.xml.
MainActivity.registerIntentAction(StringToJString('com.wa.ZebraDW.ACTION'));
TMessageManager.DefaultManager.SubscribeToMessage(TMessageReceivedNotification, HandleActivityMessage);
end;
procedure TForm1.HandleActivityMessage(const Sender: TObject; const M: TMessage);
begin
if M is TMessageReceivedNotification then
HandleIntentAction(TMessageReceivedNotification(M).Value);
end;
function TForm1.HandleAppEvent(AAppEvent: TApplicationEvent; AContext: TObject): Boolean;
var
StartupIntent: JIntent;
begin
Result := False;
if AAppEvent = TApplicationEvent.BecameActive then
begin
StartupIntent := MainActivity.getIntent;
if StartupIntent <> nil then
HandleIntentAction(StartupIntent);
end;
end;
function TForm1.HandleIntentAction(const Data: JIntent): Boolean;
var
JStr: JString;
begin
Result := False;
if (Data <> nil)
and Data.getAction.equals(StringToJString('com.wa.ZebraDW.ACTION')) then
begin
JStr := Data.getStringExtra(StringToJString('com.symbol.datawedge.data_string'));
Memo1.Lines.Add(TimeToStr(Now) + ': ' + JStringToString(JStr));
Invalidate;
end;
end;
我有一个 ZEBRA TC20,我已经根据本指南配置了 DataWedge:
https://techdocs.zebra.com/datawedge/6-6/guide/api/tutorials/
我做的唯一不同是 Intent Action:com.xlr.ACTION
在 Delphi 中,我有以下单元来处理这个(从 Embarcadero 找到示例):
unit uScanner;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, System.Messaging, FMX.Platform,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, Androidapi.JNI.GraphicsContentViewText,
FMX.Controls.Presentation, FMX.StdCtrls, FMX.Layouts, FMX.WebBrowser, FMX.Objects, FMX.ScrollBox, FMX.Memo;
type
TScanner = class(TForm)
Memo1: TMemo;
Label1: TLabel;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
function HandleAppEvent(AAppEvent: TApplicationEvent; Acontext: TObject) : Boolean;
procedure HandleActivityMessage(const Sender: TObject; const M: TMessage);
function HandleIntentAction(const Data: JIntent): Boolean;
public
{ Public declarations }
end;
var
Scanner: TScanner;
implementation
{$R *.fmx}
uses FMX.Platform.Android, Androidapi.JNI.JavaTypes, Androidapi.JNI.Net, Androidapi.JNI.Os, Androidapi.Helpers;
procedure TScanner.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := TCloseAction.caFree;
end;
procedure TScanner.FormCreate(Sender: TObject);
var
AppEventService : IFMXApplicationEventService;
begin
if TPlatformServices.Current.SupportsPlatformService(IFMXApplicationEventService, AppEventService) then
AppEventService.SetApplicationEventHandler(HandleAppEvent);
MainActivity.registerIntentAction(StringToJString('com.xlr.ACTION'));
TMessageManager.DefaultManager.SubscribeToMessage(TMessageReceivedNotification, HandleActivityMessage);
end;
procedure TScanner.HandleActivityMessage(const Sender: TObject; const M: TMessageBase);
begin
if M is TMessageReceivedNotification then
HandleIntentAction(TMessageReceivedNotification(M).Value);
end;
function TScanner.HandleAppEvent(AAppEvent: TApplicationEvent; Acontext: TObject): Boolean;
var
StartupIntent: JIntent;
begin
Result := False;
if AAppEvent = TApplicationEvent.BecameActive then
begin
StartupIntent := MainActivity.getIntent;
if StartupIntent <> nil then
HandleIntentACtion(StartupIntent);
end;
end;
function TScanner.HandleIntentAction(const Data: JIntent): Boolean;
var
Extras: JBundle;
begin
Result := False;
if Data <> nil then
begin
Extras := Data.getExtras;
if Extras <> nil then
Label1.Text:=JStringToString(Extras.GetString(StringToJString('com.symbol.datawedge.data_string')));
end;
end;
end.
我也修改了AndroidManifest.template.xml
,变成这样:
<?xml version="1.0" encoding="utf-8"?>
<!-- BEGIN_INCLUDE(manifest) -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="%package%"
android:versionCode="%versionCode%"
android:versionName="%versionName%"
android:installLocation="%installLocation%">
<uses-sdk android:minSdkVersion="%minSdkVersion%" android:targetSdkVersion="%targetSdkVersion%" />
<%uses-permission%>
<uses-feature android:glEsVersion="0x00020000" android:required="True"/>
<application android:persistent="%persistent%"
android:restoreAnyVersion="%restoreAnyVersion%"
android:label="%label%"
android:debuggable="%debuggable%"
android:largeHeap="%largeHeap%"
android:icon="%icon%"
android:theme="%theme%"
android:hardwareAccelerated="%hardwareAccelerated%"
android:resizeableActivity="false">
<%provider%>
<%application-meta-data%>
<%uses-libraries%>
<%services%>
<!-- Our activity is a subclass of the built-in NativeActivity framework class.
This will take care of integrating with our NDK code. -->
<activity android:name="com.embarcadero.firemonkey.FMXNativeActivity"
android:label="%activityLabel%"
android:configChanges="orientation|keyboard|keyboardHidden|screenSize"
android:launchMode="singleTask">
<!-- Tell NativeActivity the name of our .so -->
<meta-data android:name="android.app.lib_name"
android:value="%libNameValue%" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="com.xlr.ACTION" />
<category android:name="" />
</intent-filter>
</activity>
<%activity%>
<%receivers%>
</application>
</manifest>
<!-- END_INCLUDE(manifest) -->
我已经在调试模式下启动了应用程序,并在 HandleActivityMessage
处设置了一个断点,但没有任何反应。
有人可以帮我一下吗?
procedure TForm1.FormCreate(Sender: TObject);
var
AppEventService: IFMXApplicationEventService;
begin
if TPlatformServices.Current.SupportsPlatformService(IFMXApplicationEventService, AppEventService) then
AppEventService.SetApplicationEventHandler(HandleAppEvent);
// Register the type of intent action that we want to be able to receive.
// Note: A corresponding <action> tag must also exist in the <intent-filter> section of AndroidManifest.template.xml.
MainActivity.registerIntentAction(StringToJString('com.wa.ZebraDW.ACTION'));
TMessageManager.DefaultManager.SubscribeToMessage(TMessageReceivedNotification, HandleActivityMessage);
end;
procedure TForm1.HandleActivityMessage(const Sender: TObject; const M: TMessage);
begin
if M is TMessageReceivedNotification then
HandleIntentAction(TMessageReceivedNotification(M).Value);
end;
function TForm1.HandleAppEvent(AAppEvent: TApplicationEvent; AContext: TObject): Boolean;
var
StartupIntent: JIntent;
begin
Result := False;
if AAppEvent = TApplicationEvent.BecameActive then
begin
StartupIntent := MainActivity.getIntent;
if StartupIntent <> nil then
HandleIntentAction(StartupIntent);
end;
end;
function TForm1.HandleIntentAction(const Data: JIntent): Boolean;
var
JStr: JString;
begin
Result := False;
if (Data <> nil)
and Data.getAction.equals(StringToJString('com.wa.ZebraDW.ACTION')) then
begin
JStr := Data.getStringExtra(StringToJString('com.symbol.datawedge.data_string'));
Memo1.Lines.Add(TimeToStr(Now) + ': ' + JStringToString(JStr));
Invalidate;
end;
end;