0

Using C++ Builder 10.1 Berlin, I'm developping an app to scan barcodes on an Android device. To get a barcode I call the ZXing app by Intent. When I scan a GSI-128 barcode, the return type is CODE-128. In my app, the processing is different depending on the type of barcode (128 and GSI-128).

Is there a method to differentiate these types of barcode?

Terry Burton
  • 2,801
  • 1
  • 29
  • 41
Dylan
  • 107
  • 8

2 Answers2

0

See ZXing's documentation:

Scanning Via Intent

ZXing provides an IntentIntegrator class to initiate scans and parse the results. The barcode type is in the ScanResults.formatName field.

If you don't want to use IntentIntegrator, you will have to parse the result Intent manually. The barcode type is available in the Intent's SCAN_RESULT_FORMAT extra string field.

Either way, you can use FireMonkey's messaging framework to receive the result Intent. It will be wrapped inside of a TMessageResultNotification message.

Here is an example of ZXing scanning in Delphi from Brian Long's blog:

Launching activities and handling results in Delphi XE6 Android apps: Scanning a bar code

function LaunchActivityForResult(const Intent: JIntent; RequestCode: Integer): Boolean;
var
   ResolveInfo: JResolveInfo;
begin
   ResolveInfo := SharedActivity.getPackageManager.resolveActivity(Intent, 0);
   Result := ResolveInfo <> nil;
   if Result then
     SharedActivity.startActivityForResult(Intent, RequestCode);
end;

//For more info see https://github.com/zxing/zxing/wiki/Scanning-Via-Intent
procedure LaunchQRScanner(RequestCode: Integer);
var
   Intent: JIntent;
begin
   Intent := TJIntent.JavaClass.init(StringToJString('com.google.zxing.client.android.SCAN'));
   Intent.setPackage(StringToJString('com.google.zxing.client.android'));
   // If you want to target QR codes
   //Intent.putExtra(StringToJString('SCAN_MODE'), StringToJString('QR_CODE_MODE'));
   if not LaunchActivityForResult(Intent, RequestCode) then
     Toast('Cannot display QR scanner', ShortToast);
end;

uses
   System.Messaging,
   ...

type
   TMainForm = class(TForm)
     ...
   private
     const ScanRequestCode = 0;
     var FMessageSubscriptionID: Integer;
     procedure HandleActivityMessage(const Sender: TObject; const M: TMessage);
     function OnActivityResult(RequestCode, ResultCode: Integer; Data: JIntent): Boolean;
     ...
   end;
...
uses
   FMX.Platform.Android,
   Androidapi.Helpers,
   Androidapi.JNI.App,
   Androidapi.JNI.Toast,
   LaunchActivities,
   ...
procedure TMainForm.BarcodeScannerButtonClick(Sender: TObject);
begin
   FMessageSubscriptionID := TMessageManager.DefaultManager.SubscribeToMessage(TMessageResultNotification,
     HandleActivityMessage);
   LaunchQRScanner(ScanRequestCode);
end;

procedure TMainForm.HandleActivityMessage(const Sender: TObject; const M: TMessage);
begin
   if M is TMessageResultNotification then
     OnActivityResult(TMessageResultNotification(M).RequestCode, TMessageResultNotification(M).ResultCode,
       TMessageResultNotification(M).Value);
end;

function TMainForm.OnActivityResult(RequestCode, ResultCode: Integer; Data: JIntent): Boolean;
var
   ScanContent, ScanFormat: string;
begin
   Result :=  False;

   TMessageManager.DefaultManager.Unsubscribe(TMessageResultNotification, FMessageSubscriptionID);
   FMessageSubscriptionID := 0;

   // For more info see https://github.com/zxing/zxing/wiki/Scanning-Via-Intent
   if RequestCode = ScanRequestCode then
   begin
     if ResultCode = TJActivity.JavaClass.RESULT_OK then
     begin
       if Assigned(Data) then
       begin
         ScanContent := JStringToString(Data.getStringExtra(StringToJString('SCAN_RESULT')));
         ScanFormat := JStringToString(Data.getStringExtra(StringToJString('SCAN_RESULT_FORMAT')));
         Toast(Format('Found %s format barcode:'#10'%s', [ScanFormat, ScanContent]), LongToast);
       end;
     end
     else if ResultCode = TJActivity.JavaClass.RESULT_CANCELED then
     begin
       Toast('You cancelled the scan', ShortToast);
     end;
     Result :=  True;
   end;
end;
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Thanks Remy but I already did this but for both 128 and GSI-128 barcodes, the value of the `SCAN_RESULT_FORMAT` is the same (`CODE-128`). – Dylan Sep 19 '16 at 06:14
0

Before calling the Intent with startActivityForResult(intent,0);, just add an argument with intent->putExtra(StringToJString("ASSUME_GS1"), true);. If the barcode is a GS1-128, the prefix "]C1" would be add at your barcode.

_di_JIntent intent;
msgID = TMessageManager::DefaultManager->SubscribeToMessage(__classid(TMessageResultNotification), &retourScanTel);
intent = TJIntent::Create();
intent->setAction(StringToJString("com.google.zxing.client.android.SCAN"));
intent->putExtra(StringToJString("ASSUME_GS1"), true);
SharedActivity()->startActivityForResult(intent,0);
Dylan
  • 107
  • 8