Jump to content

toufik

Members
  • Content Count

    75
  • Joined

  • Last visited

Posts posted by toufik


  1. 4 hours ago, Dave Nottage said:

    It's supposed to be backward compatible. You should use the OnError event of InAppPurchase1 to find out what the failure is.

     

    after i add the code below no error nothing just like the first submit any idea ?
     

     types
     procedure InAppPurchase1Error(Sender: TObject; ErrorKind: TFailureKind;
          const ErrorMessage: string);
    
    
    procedure TFormMain.FormCreate(Sender: TObject);
    begin
    // the code before then ....this 
         InAppPurchase1.OnError := InAppPurchase1Error;
         end;
         
    
     procedure TFormMain.InAppPurchase1Error(Sender: TObject;
      ErrorKind: TFailureKind; const ErrorMessage: string);
    begin
     ShowMessage('Une erreur est survenue pendant l''achat : ' + ErrorMessage);
    end;

     


  2. hello everyone a few days ago i did tried to implement a one time purchase (make a paid android app )
    there is no error showing except the message that i will show you next 
    thing i did consider: 
    Make sure the product ID in your code matches the ID of the product you created in the Google Play Console.
    Make sure that the product is published and active in the Google Play Console.
    Make sure that the account you are using to test the app is not the same account you used to create the product in the Google Play Console.
    i don't know what I'm missing i keep thinking that the new library is the problem (because its come with new change to how to implement purchase) 
    i did publish the app in Internal testing. 

    i did multiply approach and multiply attempt to fix this with no luck yet with the help of chat gpt .
    ps : following this topic. 
    D11,unsupported version of Play billing - Cross-platform - Delphi-PRAXiS [en] (delphipraxis.net)

    my code:

    uses 
      FMX.InAppPurchase;
    
    types
          procedure InAppPurchaseSetupComplete(Sender: TObject);
        procedure InAppPurchaseProductsRequestResponse(Sender: TObject;
          const Products: TIAPProductList; const InvalidProductIDs: TStrings);
        procedure InAppPurchasePurchaseCompleted(Sender: TObject;
          const ProductID: string; NewTransaction: Boolean);
    
    private 
      function Purchase(const ProductId: string): Boolean;
    
    const
      NoAdsId = 'barcoderpro';
     var
      FProductIsValid: Boolean;
      fisPurchased :Boolean;
    
    procedure TFormMain.FormCreate(Sender: TObject);
    {$IFDEF ANDROID}
    
      InAppPurchase1.ApplicationLicenseKey := 'key part 1'+ 'key part 2';
       InAppPurchase1.ProductIDs.Add(NoAdsId);
       InAppPurchase1.OnSetupComplete := InAppPurchaseSetupComplete;
       InAppPurchase1.OnProductsRequestResponse := InAppPurchaseProductsRequestResponse;
       InAppPurchase1.OnPurchaseCompleted := InAppPurchasePurchaseCompleted;
    
     {$ENDIF}
     end;
    
     procedure TFormMain.InAppPurchaseSetupComplete(Sender: TObject);
    begin
      FIsPurchased := False;
      try
        InAppPurchase1.QueryProducts;
      except
        on E: Exception do
          ShowMessage(e.Message);
      end;
    end;
    
     procedure TFormMain.InAppPurchaseProductsRequestResponse(Sender: TObject;
      const Products: TIAPProductList; const InvalidProductIDs: TStrings);
    var
      Product: TProduct;
    begin
      FIsPurchased := False;
      for Product in Products do
      begin
        if NoAdsId = Product.ProductID then
        begin
          FProductIsValid := True;
          if InAppPurchase1.IsProductPurchased(NoAdsId) then
          begin
            FIsPurchased := True;  // PURCHASED!
            ShowMessage('La version professionnelle est déjà activée');
          end;
        end;
      end;
    end;
    
    
    procedure TFormMain.InAppPurchasePurchaseCompleted(Sender: TObject;
      const ProductID: string; NewTransaction: Boolean);
    begin
      if NewTransaction then
      begin
        ShowMessage('La version professionnelle activée');
        FIsPurchased := True;
      end
      else
        ShowMessage('L''achat a été annulé');
    end;
    
    function TFormMain.Purchase(const ProductId: string): Boolean;
    begin
      Result := False;
    
      {$IFDEF ANDROID}
      if InAppPurchase1.IsSetupComplete and InAppPurchase1.CanMakeInAppPurchases then
      begin
        InAppPurchase1.PurchaseProduct(ProductId);
        Result := True;
      end
      else
        ShowMessage('L''achat n''est pas possible pour le moment. Essayez plus tard.');
    
      {$ENDIF}
    end;
    
    
    procedure TFormMain.btn7Click(Sender: TObject);
    begin
      // User is not registered yet or trial period has expired, proceed with purchase
      if Purchase(NoAdsId) then begin
        // Purchase successful
    //active the app pro // no  trial period 
    end;
    //////or 
    
     if FIsPurchased then
      begin
        ShowMessage('La version professionnelle est déjà activée');
      end
      else
      begin
        // User is not registered yet or trial period has expired, proceed with purchase
        if Purchase(NoAdsId) then
        begin
          // Purchase successful
          ShowMessage('La version professionnelle est activée.....');
        end;
      end;
     

     


  3. 1 hour ago, Dave Nottage said:

    I've since seen your reply on Facebook, which indicates you're interested in the new features. I'll take a look into what changes might be possible, however it would be at least later in the week.

    i read that the new library come with some few new properties change i'm looking to it.
    Google Play Billing Library 4 to 5 Migration Guide  |  Google Play's billing system  |  Android Developers

    • Like 1

  4. 4 minutes ago, Dave Nottage said:

    Genuine question: Which code do you think you need to update, and why? To support subscriptions (which apparently are new in v5), or something else?

    I'm trying to implement one time pruchase (i'm making a paid app ) 
    so i did finish the code using belling v 4 i did not test it yet , i can share it 
    so i do not know at all how handle the new update .
     

    
    uses FMX.InAppPurchase
    types 
    
        procedure InAppPurchaseSetupComplete(Sender: TObject);
        procedure InAppPurchaseProductsRequestResponse(Sender: TObject;
          const Products: TIAPProductList; const InvalidProductIDs: TStrings);
    //    procedure InAppPurchaseError(Sender: TObject;
    //    FailureKind: TFailureKind; const ErrorMessage: string);
        procedure InAppPurchasePurchaseCompleted(Sender: TObject;
          const ProductID: string; NewTransaction: Boolean);
    const
     Nodemotrail = 'com.********.nameappid';
     var
      FProductIsValid: Boolean;
    var
    fisPurchased :Boolean;
    
    procedure TFormMain.FormCreate(Sender: TObject);
    begin
    {$IFDEF ANDROID}
      InAppPurchase1.ApplicationLicenseKey := 'LicenseKey part1'+ 'LicenseKey part2';
      InAppPurchase1.ProductIDs.Add(Nodemotrail);
       InAppPurchase1.OnSetupComplete := InAppPurchaseSetupComplete;
     {$ENDIF}
    
    procedure TFormMain.InAppPurchaseProductsRequestResponse(Sender: TObject;
      const Products: TIAPProductList; const InvalidProductIDs: TStrings);
    var
      Product: TProduct;
    begin
     fisPurchased := false;
      for Product in Products do
        begin
          if Nodemotrail = Product.ProductID    then
            begin
               FProductIsValid := True;
               if InAppPurchase1.IsProductPurchased(Nodemotrail) then
                 begin
                   fisPurchased := true;  // PURCHASED!
    
                 end
            end;
        end;
    end;
    
    procedure TFormMain.InAppPurchasePurchaseCompleted(Sender: TObject;
      const ProductID: string; NewTransaction: Boolean);
    begin
      ShowMessage('La version professionnelle activée');
      fisPurchased := True
    end;
    
    
    procedure TFormMain.InAppPurchaseSetupComplete(Sender: TObject);
    begin
    fisPurchased := False;
      try
        InAppPurchase1.QueryProducts;
      except
        on E:Exception do ShowMessage(e.Message);
      end;
    end;
    
    
    function TFormMain.Purchase(const ProductId: string): Boolean;
    begin
      Result := False;
    
      {$IFDEF ANDROID}
      if InAppPurchase1.IsSetupComplete and InAppPurchase1.CanMakeInAppPurchases then
      begin
        InAppPurchase1.PurchaseProduct(ProductId);
        Result := True;
      end
      else
        ShowMessage('Purchase not possibl now try later');
    
      {$ENDIF}
    end;
    
    
    procedure TFormMain.btn7Click(Sender: TObject);
    begin
      // User is not registered yet or trial period has expired, proceed with purchase
      if Purchase(NoAdsId) then begin
        // Purchase successful
    .....

     


  5. On 5/4/2023 at 7:52 AM, Patrick PREMARTIN said:

    did you initialized Android libraries dependencies in your project (from project manager / platform / android / library and contextual menu) ?

    (the SDK changed in 11.0 and in 11.2)

    as you can see all the library there but say billing library is 4.0.0 wish mean that google needed 5 and up 
    how to update it ?
    and i added 
      <uses-permission android:name="com.android.vending.BILLING" /> to the 
    AndroidManifest.template.xml file
    and this line to uses  FMX.InAppPurchase 

    Capture d’écran 2023-05-07 163824.png

     

    Capture d’écran 2023-05-07 180203.png

    Capture d’écran 2023-05-07 180228.png

    Capture d’écran 2023-05-07 180244.png

    Capture d’écran 2023-05-07 180339.png


  6. hello every one ...
    I'm trying pagination with SQLite database using live binding with a  tlistview  i did try using this guide:

    DB Pagination and TListView question - Databases - Delphi-PRAXiS [en] (delphipraxis.net)
    with some modification so i added the implement of pagination on  PullToRefresh of the tlistview and work's fine .

    the problem that .... i want to keep the items that added to the tlistview every PullToRefresh and so on 
    the code I used, can anyone point me to the right direction. 
     

    procedure TFormMain.ListView2MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Single);
    begin
     if PullToRefreshCheck then
     begin
       if (Y-RefreshPos)>40 then    begin
      if (FDTableTask.RecordCount < lMyMaxRecordsByPage) then
        exit;
      //
      FDTableTask.Disconnect;
      FDTableTask.FetchOptions.RecsSkip := FDTableTask.FetchOptions.RecsSkip + lMyMaxRecordsByPage;
      FDTableTask.Open();
    
        Label48.Text := '...تحديث';
         Label48.Visible := True;
         Timer3.Enabled := True;
         PullToRefreshCheck := False;
         RefreshPos := 0;
       end else begin
    Label48.Text := 'u retched the end ';
    end;
     end;

     

     


  7. 16 minutes ago, programmerdelphi2k said:
    
    FDSQLiteBackup1.Database := 'c:\db.sdb';
    FDSQLiteBackup1.DestDatabase := 'c:\db.backup';
    FDSQLiteBackup1.DestMode := smCreate;  // <---
    FDSQLiteBackup1.Backup;
    

    the error i'm having on android not windows ,windows every thing fine i just can use filecopy to do that ,,thanks for reply 


  8. 27 minutes ago, sjordi said:

    Do you actually create the "BackupFile"?
    With its structure (built-in tables)?
    I think that the file should exist first before being able to open it.
    Also make sure that you create the file somewhere where you have the right to write (sandboxing), either it the app space or in the public space.

    maybe i wasn't very clear,,,, i want the user to be able to back up the db in any folder i chose too for example :

    GetSharedPicturesPath

    . with all its structure and data and restore if he wants too 
    to answer the second question, i create the db on create ,, and filled  the table and its structure,
    the last part i will try it and get back to you soon as possible,,, thanks for taking the time to reply .


  9. hello every one ; using delphi 10.4.2 

    i need some help 
    im trying to backup a sqllite database like this :

    var msg,CommonPath: string;
      SourceFile: string;
      BackupFile: string;
    
    begin     FireTaskList.connected := False;
        SourceFile := TPath.combine(TPath.GetDocumentsPath,'tasks.s3db');//     TPath.GetDocumentsPath +PathDelim+  'tasks.s3db';
       BackupFile := TPath.Combine( TPath.GetSharedPicturesPath,  'MyBackup.s3db');
     if  not FileExists(SourceFile) then     Exit;
    
    
    
        msg := 'Create a file in the following location ' + sLineBreak+
                ExtractFilePath(BackupFile);
        TDialogService.MessageDialog(
            msg,
            TMsgDlgType.mtConfirmation,
            mbYesNo,
            TMsgDlgBtn.mbYes,
            0,
            procedure(const AResult: TModalResult)
            begin
                if AResult=mrYes then begin
                    try
    
      FDSQLiteBackup1.Database := SourceFile;
      FDSQLiteBackup1.DestDatabase := BackupFile;
      FDSQLiteBackup1.Backup;
                        ShowMessage( ExtractFileName(BackupFile)+' ...'+'saved' );
                    except
                        on E: Exception do begin
                            msg := E.ClassName + sLineBreak + E.Message;
                            ShowMessage( msg );    mmo1.text :=   BackupFile;
                        end;
                    end;
                end;
            end
        );
    
    end;

    and im keep getting an error message 
    i did set the read and write permissions 

    and i connected the database like this 

    try
    
        FireTaskList.Connected := False;
        FireTaskList.Params.Clear;
        FireTaskList.LoginPrompt := False;
        FireTaskList.Params.Values['OpenMode'] :='=ReadWrite';
        FireTaskList.Params.DriverID := 'SQLite';
        FireTaskList.Params.Values['Database'] := TPath.combine(TPath.GetDocumentsPath,'tasks.s3db');
    
      except
        on E: EDatabaseError do
          ShowMessag('cant connect' + E.Message);

     

    Screenshot_2022-12-09-10-23-27-645_com.embarcadero.BarCoder.jpg


  10. the answer is 
     

    procedure TForm1.Delete;
    begin
      dm.fdmedcin.RecNo := ControlList1.ItemIndex + 1; // seems like you add one in your OnBeforeDrawItem too
      dm.fdmedcin.Delete;
      ControlList1.ItemCount := fdmedcin.RecordCount;
    end;

  11. I'm new to using  component TControlList  can someone help with this 
    How exactly can a selected field or item from the TControlList can  be deleted?

    i'm loding the items like this 
    procedure TForm1.ControlList1BeforeDrawItem(AIndex: Integer; ACanvas: TCanvas;
      ARect: TRect; AState: TOwnerDrawState);
    begin
    dm.fdmedcin.RecNo := AIndex+1;
    lbl5.Caption := 'Spc:' +TStringField( dm.fdmedcin.FieldByName('Spc_doc') ).AsString ;
    .........

    .........

    ........

    procedure TDM.fdmedcinAfterOpen(DataSet: TDataSet);
    begin
    form1.ControlList1.ItemCount := fdmedcin.RecordCount;

     

    Untitled.png


  12. 6 hours ago, Attila Kovacs said:

    Your button texts are colorful, that means you have visual styles turned off, but it's needed to show texthint

    can you explain more how to do that please?


  13. Just now, Attila Kovacs said:

    then why are you writing hint in the topic if you are such an eagle eye?

    otherwise no clue. debug the VCL

    you were right its a ''focus''  problem now i feel very stupid thank you for all your help 


  14. Just now, Attila Kovacs said:

    texthint is not hint, hint is empty and edit is focused so you can't see anything

    i don't want to show a balloon hint i want to show a hint inside an edit once the user selects it , it clear 


  15. On 9/26/2022 at 11:32 AM, rvk said:

    If it's just some values you need it might be easier to just extract the .xlsx and read the values from the sheet1.xml.

    Also changing them (and rezipping them to a new .xlsx) won't be a problem.

     

    Adding value might become somewhat more difficult and needs some understanding of the xml structures.

     

    thanks for reply i will try that and get back to you 


  16. 3 hours ago, Remy Lebeau said:

    First, do not store your INI file in the same folder as your EXE. If the EXE is installed in a protected folder, like under %ProgramFiles%, then this will not work.  You should instead save the INI file in a subfolder you create for your app under the user's %APPDATA% folder, for instance.

     

    Second, use (Write|Read)Integer() instead of (Write|Read)String().

     

    Third, what is the value of SkinFile?  And did you verify that the restoration code is using the same value?

    You are not loading from the same file that you saved to.  Also, why are you checking the current ItemIndex value before loading the value from the INI file?

     

    With that said, try something more like this:

     

    
    uses
      ..., SysUtils, ComObj, SHFolder;
      
    procedure TMyForm.GetINIFilePath(CanCreate: Boolean): string;
    var
      AppDataPath: array[0..MAX_PATH] of Char;
    begin
      OleCheck(SHGetFolderPath(Handle, CSIDL_APPDATA, 0, SHGFP_TYPE_CURRENT, AppDataPath));
      Result := IncludeTrailingPathDelimiter(AppDataPath) + 'MyApp';
      if CanCreate then
        ForceDirectories(Result);
      Result := IncludeTrailingPathDelimiter(Result) + 'my.ini';
    end;
    
    procedure TMyForm.SaveINI;
    var
      Myinifile: TIniFile;
      SkinFile: string;
    begin
      SkinFile := ...;
      Myinifile := TIniFile.Create(GetINIFilePath(True));
      try
        Myinifile.WriteInteger('LastDiskSkin', SkinFile, lst1.ItemIndex);
        ...
      finally
        Myinifile.Free;
      end;
    end;
    
    procedure TMyForm.LoadINI;
    var
      Myinifile: TIniFile;
    begin
      SkinFile := ...;
      Myinifile := TIniFile.Create(GetINIFilePath(False));
      try
        lst1.ItemIndex := Myinifile.ReadInteger('LastDiskSkin', SkinFile, -1);
        ...
      finally
        Myinifile.Free;
      end;
    end;
    
    procedure TMyForm.FormCreate(Sender: TObject);
    begin
      LoadINI;
    end;
    
    procedure TMyForm.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
      SaveINI;
    end;

     

    worked great, with some tweaks 
    i replaced ,procedure with function 
    and handle in line 7 with HWND_DESKTOP for some reason i did get an error with it  
    (([dcc32 Error] Unit1.pas(192): E2003 Undeclared identifier: 'Handle'))
    thank you and everyone else who tried to help 
    by the way big fan of your work here and in every other platform,, great job,, take care everyone and have a nice day or a night ....

×