Search code examples
androiddelphilistboxandroid-4.4-kitkatdelphi-xe8

How to extract original JString value from Listbox in Android Kitkat Delphi XE8


I am making a test android multidevice application with Delphi xe8. I am attaching objects to the items in a listbox as follows:

 unit Unit1;

 interface

 uses
  System.SysUtils, System.Types, System.UITypes, System.Classes,  
   System.Variants,

  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics,    
  Androidapi.JNI.JavaTypes, FMX.Dialogs,
 FMX.Controls.Presentation, FMX.StdCtrls, FMX.Layouts, FMX.ListBox,    
 Androidapi.Helpers;

 type
   TForm1 = class(TForm)
   ListBox1: TListBox;
   Button1: TButton;
   Button2: TButton;
   procedure Button1Click(Sender: TObject);
   procedure Button2Click(Sender: TObject);
   private
   { Private declarations }
   public
   { Public declarations }
   end;

     var
    Form1: TForm1;

    implementation
    {$R *.fmx}

    //this where I am Attaching objects to items
    procedure TForm1.Button1Click(Sender: TObject);
    var
    str:string;
    jstr1:JString;
    begin
    str:='apple';
    jstr1:=StringToJString(str);
    ListBox1.Items.AddObject('fruit', TObject(jstr1));
    end;


    //this where I am extracting the jstring objects
    procedure TForm1.Button2Click(Sender: TObject);
     var
    jstr2:JString;
    str2:string;
    begin
    jstr2:=JString(ListBox1.Items.Objects[i]);
    str2:=JStringToString(jstr2);
    showmessage('the fruit of the day is '+str2);
    end;

   end.

The above code run ok and the jstring objects are attached to the items, however, when I want extract the jstring object that has been attached to the item, I do this:

 jstr2:=JString(ListBox1.Items.Objects[i]);
 //Above give me an AV: I get incompatible types TObject and JString

 str2:=JStringToString(jstr2);

The above code does not compile because of incompatible types TObject and JString. But yet if had attached a string as the object(instead of a jstring) and wanted to get back those string objects I could just do:

str2:=String(ListBox1.Items.Objects[i]);

This would work with regular strings. How do I solve this problem, attach and extract jstring?


Solution

  • This is just a suggestion, and I can not check this (nothing installed here), but you could write a simple object type and store that (I put it in its own unit, which you then use in your form unit):

    unit StringObjs;
    
    interface
    
    uses 
      Androidapi.JNI.JavaTypes;
    
    type
      TStringObj = class
      private
        FPayload: string;
      public
        constructor Create(const Payload: JString);
        class operator Explicit(const Obj: TStringObj): string;
      end;
    
    implementation
    
    uses
      Androidapi.Helpers;
    
    constructor TStringObj.Create(const Payload: JString);
    begin
      FPayload := JStringToString(Payload); // store string, not JString!
    end;
    
    class operator TStringObj.Explicit(const Obj: TStringObj): string;
    begin
      Result := Obj.FPlayload;
    end;
    
    end.
    

    And you use it in your form unit's implementation section like:

    implementation
    
    uses ..., StringObjs;
    
    ...
    
      ListBox1.Items.AddObject('fruit', TStringObj.Create(jstr1));
    

    and reverse:

      MyString := string(ListBox1.Items[0] as TStringObj);
    

    Note that a form is just a class, but one that the IDE knows about and can edit using the form designer. To declare other classes, do something similar as I do above. Read the Delphi Language Guide to learn more.