6
votes

In my app, developed with XE7 for Android/iOS, I have a form for scanning barcodes. Upon a found barcode, my app validates whether it is an acceptable barcode or not. Following tutorials here: http://www.fmxexpress.com/qr-code-scanner-source-code-for-delphi-xe5-firemonkey-on-android-and-ios/

Currently I am testing on Android and I am able to integrate scanning and reading of barcodes, but the 'onBarCode' event does not fire when returned from the shared Activity of finding the barcode. Same code worked well with previous versions of Rad Studio ( XE4, XE5, XE6) but now in XE7 it does not.

Here are some snippets of code:

...
begin
    Scanner := TAndroidBarcodeScanner.Create(true);
    Scanner.OnBarCode := BarcodeHandler;
    Scanner.Scan;
end;

procedure TmScannerForm.BarcodeHandler(Sender: TAndroidBarcodeScanner;
  BarCode: String);
begin
  text1.Text := Barcode;
  memo1.PasteFromClipboard;
  AddBarcode(BarCode, true);
end;

AddBarCode is the even I used to validate and add barcode to a list, but I didnt include it, because that code isn't the problem - it's not even triggering. The Text1.text:=Barcode and memo1.paseFromClipboard were in their for validating the even wasn't firing too. I can confirm the barcodes are being read because if I tap and manually paste, the barcode shows.

Why is this not working on XE7 as it did in previous versions of Rad Studio?

4
Which Android barcode reader is it? (the class name TAndroidBarcodeReader does not indicate if it is zbar or zxing based)mjn
fmxexpress.com/wp-content/uploads/2014/03/TKRBarCodeSanner.zip is the third link where it lists resources for the article to get going on the scanningThisGuy
The TTKRBarCodeScanner class in the zip uses com.google.zxing.client.android.SCAN, so I assume it is ZXing based. Actually you could use the lines shown in my answer instead of the component / class TAndroidBarcodeScanner (which seems to be in the 20.3 MB download at cc.embarcadero.com/Download.aspx?id=29699 if I understand correctly)mjn

4 Answers

6
votes

Andrea Magni has a more elegant solution than the timer on his blog based on event handling.

I would comment to send the link but I don't have enough reputation. The link to his blog is :

http://blog.delphiedintorni.it/2014/10/leggere-e-produrre-barcode-con-delphi.html

Maybe this can help you. The blog is in Italian though but the sources are provided and are explaining by themselves.

2
votes

There is a source code fragment on http://john.whitham.me.uk/xe5/ which looks useable (based on Zxing):

 intent := tjintent.Create;     
 intent.setAction(stringtojstring('com.google.zxing.client.android.SCAN'));
 sharedactivity.startActivityForResult(intent,0);

The code in the linked article also shows how to receive the Intent result. (I don't work with Delphi on Android so I am not sure if that part uses a best practice - TTKRBarCodeScanner uses a workaround with a Timer and the Clipboard).

I would try this as an alternative to see if works.

1
votes

This code works to me!

Set timer enabled to true when you run your scan code

procedure Tform.Timer1Timer(Sender: TObject);
begin
if  (ClipService.GetClipboard.ToString <> '')  then
  begin
     timer1.Enabled:=false;
      zSearch.Text := ClipService.GetClipboard.ToString;
     //Do what you need
  end;

end;
1
votes

This code to me works fine!

in andorid.BarcodeScanner

function TAndroidBarcodeScanner.HandleAppEvent(AAppEvent: TApplicationEvent;
  AContext: TObject): Boolean;
var
  aeBecameActive : TApplicationEvent;
begin
  aeBecameActive := TApplicationEvent.BecameActive;
  if FMonitorClipboard and (AAppEvent = aeBecameActive) then
  begin
    GetBarcodeValue;
  end;
end;