How can I access the elements returned by the KeyCharacterMap.getEvents function from Delphi?

I am trying to use a function JKeyCharacterMap.getEventsfrom Delphi to get KeyCode from Char.

So, I am using this code.

uses
  FMX.Platform.Android,
  Androidapi.Helpers,
  Androidapi.JNIBridge;

var
  s : string;
  PlatformKey : Word;
  FKeyCharacterMap: JKeyCharacterMap;
  events  : TJavaObjectArray<JKeyEvent>;
  event   : JKeyEvent;
  chars: TJavaArray<Char>;
  l : integer;
begin
  FKeyCharacterMap := TJKeyCharacterMap.JavaClass.load(TJKeyCharacterMap.JavaClass.BUILT_IN_KEYBOARD);

  chars    := TJavaArray<Char>.Create(1);
  chars[0] := 'A';
  events   := FKeyCharacterMap.getEvents(chars);

  l := events.Length; //this returns 4
  if l>0 then
  begin
   event := events[0]; // Segmentation fault (11)
   PlatformKey := event.getKeyCode;
  end;

end;

but unfortunately, as soon as I try to access some element of the array returned by the function JKeyCharacterMap.getEvents, I get an exception Segmentation fault (11).

So the question is, how can I access the elements returned by the KeyCharacterMap.getEvents function from Delphi?

UPDATE

I debugged using a breakpoint at which an exception was thrown and the application fails in this function Androidapi.JNIBridge.TJNIResolver.GetObjectArrayElementbecause the variable JNIEnvResis nil

class function TJNIResolver.GetObjectArrayElement(AArray: JNIObjectArray; Index: JNISize): JNIObject;
begin
  GetJNIEnv;
  //JNIEnvRes is nil
  Result := JNIEnvRes^.GetObjectArrayElement(JNIEnvRes, AArray, Index);
end;

The function GetJNIEnvdoes not assign a value to a variable JNIEnvRes.

class function TJNIResolver.GetJNIEnv: PJNIEnv;
begin
  if JNIEnvRes = nil then
    PJavaVM(System.JavaMachine)^.AttachCurrentThread(System.JavaMachine, @JNIEnvRes, nil);
  Result := JNIEnvRes;
end;

, .

+4
1

GetJNIEnv . , nil, Delphi JNIEnvRes, , Result nil:

class function TJNIResolver.GetJNIEnv: PJNIEnv;
begin
  if JNIEnvRes = nil then
    PJavaVM(System.JavaMachine)^.AttachCurrentThread(System.JavaMachine, @JNIEnvRes, nil);
  Result := JNIEnvRes; 
  // debugger shows JNIEnvRes as nil and Result as not nil
end;

, GetObjectArrayElement , WrapJNIReturn , , - FClassID nil. FClassID - .

WrapJNIReturn(AObject, FClassID, FBaseType.Handle, Result);

:

1.

events := FKeyCharacterMap.getEvents(chars);

l := events.Length; //this returns 4
if l>0 then
begin
  //event := events[0]; // Fails!
  event := TJKeyEvent.Wrap(events.GetRawItem(0)); // works
  PlatformKey := event.getKeyCode;
end;

2. ClassID

events := TJavaObjectArray<JKeyEvent>.Wrap(FKeyCharacterMap.getEvents(chars));

l := events.Length; //this returns 4
if l>0 then
begin
  event := events[0]; // now working well
  PlatformKey := event.getKeyCode;
end;
+1

All Articles