Antonis
Antonis

Reputation: 55

DELPHI 10.4, receive output result via Broadcast of Barcode Scanner

I have a Sunmi L2s device, and I'm trying to receive the result of a barcode scan via a broadcast to an Android app. I would like to create an app that, when I push the hardware button for scan (orange button to the side of the phone), shows the barcode on a TLabel.Text in the app.

I've found code here on StackOverflow, but I can't make it receive the results, and I'm getting a message when the app starts that says "External exception 0".

I'm new to Delphi/Android development, so any help is welcome!

implementation

{$R *.fmx}

uses
  FMX.Platform.Android, Androidapi.JNI.JavaTypes, Androidapi.JNI.Net,  
  Androidapi.JNI.Os, Androidapi.Helpers;

procedure TForm4.FormCreate(Sender: TObject);
var
  AppEventService: IFMXApplicationEventService;
begin
  if TPlatformServices.Current.SupportsPlatformService(IFMXApplicationEventService, AppEventService) then
    AppEventService.SetApplicationEventHandler(HandleAppEvent);
      
  MainActivity.registerIntentAction(StringToJString('com.sunmi.scanner.ACTION_DATA_CODE_RECEIVED'));
  TMessageManager.DefaultManager.SubscribeToMessage(TMessageReceivedNotification, HandleActivityMessage);
end;

procedure TForm4.HandleActivityMessage(const Sender: TObject; const M: TMessage);
begin
  if M is TMessageReceivedNotification then
    HandleIntentAction(TMessageReceivedNotification(M).Value);
end;

function TForm4.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 TForm4.HandleIntentAction(const Data: JIntent): Boolean;
var
  JStr: JString;
begin
  Result := False;
  if (Data <> nil) and Data.getAction.equals(StringToJString('com.sunmi.scanner')) then
  begin
    JStr := Data.getStringExtra(StringToJString('Data'));
    Label1.Text := JStringToString(JStr);
    Invalidate;
  end;
end;

end.

Upvotes: 1

Views: 1110

Answers (2)

user2244705
user2244705

Reputation: 381

The post is a bit old, however maybe you are querying the wrong key 'Data' instead of 'data' which seems to be the right default key for sunmi device :

JStr := Data.getStringExtra(StringToJString('Data'));

Replace it by

JStr := Data.getStringExtra(StringToJString('data'));

Upvotes: 0

Remy Lebeau
Remy Lebeau

Reputation: 597101

One issue I see that could be causing your "External exception" error is that in HandleIntentAction(), Data.getAction() can potentially return nil, which you are not checking for. Also, you need to compare the complete action name, not a prefix of it.

Change this:

Data.getAction.equals(StringToJString('com.sunmi.scanner'))

To this instead:

StringToJString('com.sunmi.scanner.ACTION_DATA_CODE_RECEIVED').equals(Data.getAction)

Other than that, the only other potential issue I see is in HandleAppEvent(), are you sure BecameActive is the best event to use to handle the StartupIntent? I would think FinishedLaunching would be a more appropriate event. An app can gain and lose focus multiple times during its lifetime, so you wouldn't want to handle the same startup Intent object over and over. Otherwise, at the very least, after you have processed the StartupIntent, you could optionally call MainActivity.setIntent(nil) so that MainActivity.getIntent() won't return the same Intent object anymore on subsequent events. Or, you could simply get rid of HandleAppEvent() and just handle the StartupIntent directly in your Form's OnCreate event.

Upvotes: 3

Related Questions