Jump to content

Kast2k

Members
  • Content Count

    2
  • Joined

  • Last visited

Posts posted by Kast2k


  1. Good day, dear colleagues!

    I'm writing a software for QR data parsing from Honeywell CT50 (Android 6).

    I'm sorry for may be big lists of code but i was simplifiying as much as possible.

    Main form:

    TMainForm = class(TForm)
        Label1: TLabel;
        btnSaveToStore: TButton;
        procedure FormCreate(Sender: TObject);
      private
        { Private declarations }
        FAutomaticMode:Boolean;
    
        procedure ActivateScanner;
      public
        property AutomaticMode: Boolean read FAutomaticMode write FAutomaticMode;
    
        procedure onBarCodeCompleteThreadSwitcher;
        procedure onBarCodeFailThreadSwitcher;
    
        procedure ShowInformationMessage(const AText:string);
        { Public declarations }
      end;
    
    uses
      FMX.Helpers.Android,  Androidapi.NativeActivity,  Androidapi.JNI.Widget,
      formScanTakeOnStore, PSTypes, PSVars;
    
    procedure TMainForm.ActivateScanner;
    begin
      RegisterDelphiNativeMethods;
      TJNASC.Activate;
      Log.d('Scanner ready');
    end;
    
    procedure TMainForm.btnSaveToStoreClick(Sender: TObject);
    begin
      Barcode.DelayInSeconds:=2;
      frmScanTakeOnStore:=TfrmScanTakeOnStore.Create(Application);  //is it correct declaration or may be i need Free on Close?
      frmScanTakeOnStore.Show;
    end;
    
    procedure TMainForm.FormCreate(Sender: TObject);
    begin
      Barcode:=TBarcode.Create;
      Barcode.DelayInSeconds:=2;
      ActivateScanner; 
    end;
    
    procedure TMainForm.onBarCodeCompleteThreadSwitcher;
    begin
      if AutomaticMode then
        TJNASC.Start
      else
        TJNASC.Stop;
    end;
    
    procedure TMainForm.onBarCodeFailThreadSwitcher;
    begin
    
    end;
    
    procedure TMainForm.ShowInformationMessage(const AText: string);
    begin
      CallInUiThread (
            procedure
            begin
              TJToast.JavaClass.makeText (TAndroidHelper.Context,
                  StrToJCharSequence(AText), TJToast.JavaClass.LENGTH_LONG).show;
            end
      );
    end;

    PSTypes

    unit PSTypes;
    
    interface
    
    uses
      System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
      FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.ScrollBox,
      FMX.Memo, FMX.Controls.Presentation, FMX.StdCtrls,
      Androidapi.JNI.App,  Androidapi.JNI,  Androidapi.JNIBridge,  Androidapi.JNI.JavaTypes,
      DateUtils,  System.Character;
    
    type
      JNativeActivitySubclass = interface;
    
      JNativeActivitySubclassClass = interface(JActivityClass)
      ['{361C7073-E0A2-4A0D-B5E4-8403E5214275}']
        {Methods}
        //function init: JFMXNativeActivity; cdecl;
      end;
    
      [JavaSignature('com/winarhi/nativeactivitysubclass/NativeActivitySubclass')]
      JNativeActivitySubclass = interface(JActivity)
      ['{7141B1C4-508D-46F3-A767-E0BFCE22C9CE}']
        {Methods}
    //    procedure WA_75e_DoScan(paramBoolean :JBoolean);
        procedure WA_75e_Create_aidcManager;
        procedure WA_75e_Destroy_aidcManager;
        procedure WA_75eStart;
        procedure WA_75eStop;
      end;
      TJNativeActivitySubclass = class(TJavaGenericImport<JNativeActivitySubclassClass, JNativeActivitySubclass>)
      public
        procedure Activate;
        procedure DeActivate;
        procedure Start;
        procedure Stop;
      end;
    
      TBarcodeData=record
      end;
    
      TBarcodeResult=procedure(const BarcodeData:TBarcodeData) of object;
    
      TBarcode=class
      private
        FBarcodeData : TBarcodeData;
        FOnBarcodeResult : TBarcodeResult;
    
        procedure SetReceivedBarcodeData(const Value: string);
      public
        property OnBarcodeResult: TBarcodeResult read FOnBarcodeResult write FOnBarcodeResult;
      end;
    
    procedure RegisterDelphiNativeMethods;
    
    implementation
    
    uses
      FMX.Helpers.Android,
      Androidapi.NativeActivity, PSVars, formMain;
    
    { TJNativeActivitySubclass }
    
    procedure onBarCodeCompleteNative(PEnv: PJNIEnv; This: JNIObject; BarCode: JNIString); cdecl;
    begin
      PSVars.Barcode.ReceivedBarcodeData := JNIStringToString(PEnv, BarCode);
      TThread.Synchronize(TThread.CurrentThread, MainForm.onBarCodeCompleteThreadSwitcher);
    end;
    
    procedure onBarCodeFailNative(PEnv: PJNIEnv; This: JNIObject; BarCode: JNIString); cdecl;
    begin
      TThread.Synchronize(TThread.CurrentThread, MainForm.onBarCodeFailThreadSwitcher);
    end;
    
    procedure RegisterDelphiNativeMethods;
    var
      PEnv: PJNIEnv;
      ActivityClass: JNIClass;
      NativeMethods: array[0..1] of JNINativeMethod;
    begin
      Log.d('Starting the registration JNI stuff');
    
      PEnv := TJNIResolver.GetJNIEnv;
    
      Log.d('Registering interop methods');
    
      NativeMethods[0].Name := 'onBarCodeCompleteNative';
      NativeMethods[0].Signature := '(Ljava/lang/String;)V';
      NativeMethods[0].FnPtr := @onBarCodeCompleteNative;
    
      NativeMethods[1].Name := 'onBarCodeFailNative';
      NativeMethods[1].Signature := '()V';
      NativeMethods[1].FnPtr := @onBarCodeFailNative;
    
      ActivityClass := PEnv^.GetObjectClass(
        PEnv, PANativeActivity(System.DelphiActivity).clazz);
    
      PEnv^.RegisterNatives(PEnv, ActivityClass, @NativeMethods[0], 2);
    
      PEnv^.DeleteLocalRef(PEnv, ActivityClass);
    
      Log.d('Interop Methods Registered');
    end;
    
    procedure TJNativeActivitySubclass.Activate;
    begin
      Wrap(PANativeActivity(System.DelphiActivity)^.clazz).WA_75e_Create_aidcManager;
    end;
    
    procedure TJNativeActivitySubclass.DeActivate;
    begin
      Wrap(PANativeActivity(System.DelphiActivity)^.clazz).WA_75e_Destroy_aidcManager;
    end;
    
    procedure TJNativeActivitySubclass.Start;
    begin
      Wrap(PANativeActivity(System.DelphiActivity)^.clazz).WA_75eStart;
    end;
    
    procedure TJNativeActivitySubclass.Stop;
    begin
      Wrap(PANativeActivity(System.DelphiActivity)^.clazz).WA_75eStop;
    end;
    
    end.

    PSVars

    unit PSVars;
    
    interface
    
    uses
      PSTypes ;
    
    var
      Barcode:TBarcode;
      TJNASC:TJNativeActivitySubclass;
    
    implementation
    
    end.

    formScanTakeOnStore

    unit formScanTakeOnStore;
    
    interface
    
    uses
      System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
      FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
      FMX.Controls.Presentation, FMX.StdCtrls, FMX.ScrollBox, FMX.Memo,
      Androidapi.JNI.App,  Androidapi.JNI,  Androidapi.JNIBridge,  Androidapi.JNI.JavaTypes,
      Androidapi.Helpers, FMX.DialogService, System.Rtti, FMX.Grid.Style,
      FMX.Grid, FMX.TextLayout, DateUtils, PSTypes, FMX.Objects;
    
    type
      TfrmScanTakeOnStore = class(TForm)
        Label1: TLabel;
        btnFinish: TButton;
        Panel1: TPanel;
        Panel2: TPanel;
        Panel3: TPanel;
        btnContinuous: TButton;
        btnManual: TButton;
        Panel4: TPanel;
        lblReceived: TLabel;
        StyleBook1: TStyleBook;
        btnTable: TButton;
        lblMaterial: TLabel;
        lblBankaCounts: TLabel;
        lblTotalLeft: TLabel;
        tmrSleep: TTimer;
        rectStatus: TRectangle;
        Button1: TButton;
        procedure btnFinishClick(Sender: TObject);
        procedure FormShow(Sender: TObject);
        procedure btnContinuousClick(Sender: TObject);
        procedure btnManualClick(Sender: TObject);
        procedure btnTableClick(Sender: TObject);
        procedure tmrSleepTimer(Sender: TObject);
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
        FNewDataExist:Boolean;
    
        BarcodeData:TBarcodeData;
    
        procedure OnBarcodeResult(const ABarcodeData:TBarcodeData);
        procedure CloseFrm(Sender: TObject; const AResult: TModalResult);
        procedure MaterialAddedNG(Sender: TObject; const AResult: TModalResult);
        procedure MaterialAddedOK(Sender: TObject; const AResult: TModalResult);
        procedure StopScannerAndColor(CL:Cardinal);
      public
        { Public declarations }
      end;
    
    var
      frmScanTakeOnStore: TfrmScanTakeOnStore;
    
    implementation
    
    uses
      FMX.Helpers.Android,  Androidapi.NativeActivity, formScanComplete, dmData, formAgreeAction,
      formScanTakeOnStoreTable, PSVars, formMain;
    
    {$R *.fmx}
    
    procedure TfrmScanTakeOnStore.btnContinuousClick(Sender: TObject);
    begin
      TJNASC.Start;
      btnContinuous.StyleLookup:='btnContinuousStyle1';
      btnManual.StyleLookup:='';
      MainForm.AutomaticMode:=True;
      MainForm.ShowInformationMessage('Automatic mode');
    end;
    
    procedure TfrmScanTakeOnStore.btnFinishClick(Sender: TObject);
    begin
    //  MainForm.SayTextToSpeech('Stop data reading process and exit?');
      TDialogService.MessageDialog(
        'Stop data reading process and exit?',
        TMsgDlgType.mtWarning,
        [TMsgDlgBtn.mbYes, TMsgDlgBtn.mbNo],
        TMsgDlgBtn.mbNo,
        0,
        CloseFrm);
    end;
    
    procedure TfrmScanTakeOnStore.btnManualClick(Sender: TObject);
    begin
      TJNASC.Stop;
      btnManual.StyleLookup:='btnContinuousStyle1';
      btnContinuous.StyleLookup:='';
      MainForm.AutomaticMode:=False;
    end;
    
    procedure TfrmScanTakeOnStore.btnTableClick(Sender: TObject);
    begin
      CallInUIThread(procedure begin
        frmScanTakeOnStoreTable:=TfrmScanTakeOnStoreTable.Create(Application); //Free ???
        frmScanTakeOnStoreTable.Show;
      end);
    end;
    
    procedure TfrmScanTakeOnStore.Button1Click(Sender: TObject); //simulation
    var
      bc: TBarcodeData;
    begin
      bc.Parsed:=True;
      bc.KPJCode:='80604358';
      bc.LotName:='testlot';
      OnBarcodeResult(bc);
    end;
    
    procedure TfrmScanTakeOnStore.CloseFrm(Sender: TObject; const AResult: TModalResult);
    begin
      if AResult = mrYes then
        begin
          TJNASC.Stop;
          MainForm.AutomaticMode:=False;
          Close;
        end;
    end;
    
    procedure TfrmScanTakeOnStore.FormShow(Sender: TObject);
    begin
      Log.d('Pre-activate');
      tmrSleep.Interval:=Barcode.DelayInSeconds*1000;
    
      Barcode.LastScanTimeUnix:=DateTimeToUnix(Now);
      Barcode.OnBarcodeResult:=OnBarcodeResult;
    end;
    
    procedure TfrmScanTakeOnStore.MaterialAddedNG(Sender: TObject;
      const AResult: TModalResult);
    begin
      if AResult = mrYes then
        begin
          ///NG result parse
        end;
    end;
    
    procedure TfrmScanTakeOnStore.MaterialAddedOK(Sender: TObject;
      const AResult: TModalResult);
    begin
    
    end;
    
    procedure TfrmScanTakeOnStore.OnBarcodeResult(const ABarcodeData: TBarcodeData);
    begin
      if ABarcodeData.Parsed then
        begin
          StopScannerAndColor(TAlphaColors.Green);
        end
      else
        begin
          MainForm.ShowInformationMessage(ARNBarCode+' not recognized.');
          StopScannerAndColor(TAlphaColors.Red);
        end;
    end;
    
    procedure TfrmScanTakeOnStore.StopScannerAndColor(CL: Cardinal);
    begin
      rectStatus.Fill.Color:=CL;
      TJNASC.Stop;
      TJNASC.DeActivate;
      Log.d('Scanner DeActivate');
      tmrSleep.Enabled:=True;
    end;
    
    procedure TfrmScanTakeOnStore.tmrSleepTimer(Sender: TObject);
    begin
      TJNASC.Activate;
      Log.d('Scanner ready');
      if MainForm.AutomaticMode then
        begin
          MainForm.ShowInformationMessage('Starting scanner');
    
    ////NG
          {frmScanTakeOnStore.btnManual.OnClick(frmScanTakeOnStore.btnManual);
          Sleep(1000);
          frmScanTakeOnStore.btnContinuous.OnClick(frmScanTakeOnStore.btnContinuous);}
    ////NG
          {TJNASC.Stop;
          MainForm.AutomaticMode:=False;
          TJNASC.Start;
          MainForm.AutomaticMode:=True;}
    
          MainForm.ShowInformationMessage('Automatic mode');
        end;
      rectStatus.Fill.Color:=StrToInt('$FFE0E0E0');
      tmrSleep.Enabled:=False;
    end;
    
    end.

    So after mainform show Honeywell is activated and possible to read QRs

    After that i'm opening "frmScanTakeOnStore " and select Manual (btnManual) or Automatic (btnContinuous) scanning mode. Manual = operator presses HW button, Automatic = reading laser is always active

    TJNASC.Start, TJNASC.Stop are responsible for Automatic scanning mode: Stop = Manual, Start = Automatic On

     

    Now i have a request from user that when scanning in Automatic then after QR code reading and parsing device need to shutdown scanner on some interval (1-3 seconds) and re-activate it and continue scanning

     

    Temporary i decided to do via FMX TTimer. It works normally, notification messages are shown, BUT! scanner is not running automatic mode until i press btnContinuous.

     

    I tried 2 variants but same NG result. Also tried via CallInUIThread = same result.

     

    So the problem is that i cant start Automatic reading without manual clicking on button

     

    Dear collagues, may be i not fully understand FMX logic or doing\missing something wrong?

     

     

×