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;