Wednesday 12 February 2020

The Enter key and the OnKeyDown/OnKeyUp events on Android

A problem surfaced on Stack Overflow recently from a Delphi developer, Tom Byrnes, who discovered that on Android, the Enter (or Return) key no longer triggers the OnKeyDown and OnKeyUp events. This was unfortunate as Tom wanted to code to run in (one of) those handlers.

The problem had been reported as RSP-27496 but alas it had been closed at the time Tom was hunting for a solution (to my mind closed wrongly).

What to do?

Well, after some valiant fighting with the problem accompanied with the inevitable wailing and gnashing of teeth, Tom found a workaround of sorts. Setting the TEdit control's ReturnKeyType property Go, Search or Send allows the OnKeyDown event to fire for the Enter key. Good stuff! But not ideal....

I sent a note to a relevant party within EMBT and after reviewing the report it has since been re-opened. That's a start.

To try and be a bit more helpful I'd like to offer a solution to having the Enter key get OnKeyDown and OnKeyUp events triggered. This involves editing one of the Java files that underpins the Delphi Android FireMonkey. implementation

The default RAD Studio installation for 10.3.3 is to C:\Program Files (x86)\Embarcadero\Studio\20.0. If we assume an environment variable BDS is set to that value (as it is in a RAD Studio Command Prompt) then the Java source files can be found in:

%BDS%\source\rtl\androiddex\java\fmx\src\com\embarcadero\firemonkey

The file of interest is in a subfolder and is:

text\FMXEditText.java

so to put it another way:

%BDS%\source\rtl\androiddex\java\fmx\src\com\embarcadero\firemonkey\text\FMXEditText.java

In this file just over halfway down is a routine called onEditorAction, which needs a slight tweak. It's only a short subroutine, but if you examine the logic you'll appreciate that it contains a condition with some logic in the if section and some more logic in the else section.

The required change is to remove the else section and leave the logic currently contained there to run unconditionally. I don't want to copy out code from the RTL to avoid transgressing any inappropriate boundaries, but if the code currently looks like this:

public void onEditorAction(int actionCode) {
    if (condition) {
        // if block
    } else {
        // else block
    }
}

we want to alter it to look like this:

public void onEditorAction(int actionCode) {
    if (condition) {
        // if block
    }
    // else block
}

Assuming this is all done, what next?

Well the next step is to rebuild all the Java files and replace the compiled Java archives with the updated re-compiled ones. Fortunately I can help out there. I posted yesterday a full command script that will do just this exact job, so please make use of that to follow the required steps to get the fix.

Once you have run the script to generate new Java archives and re-built and re-run your Android app your events should trigger on Android when you press the soft Enter key.

One final thing: don't forget to backup the original Java archive files before running the script as mentioned in the post!

2 comments:

  1. Hello, just a question, why the proposed workaround is not ideal?

    ReplyDelete
    Replies
    1. Hi, it may of course be the case that you have no issue with setting ReturnKeyType as required by the workaround. However I perceived the fact of being forced to set a property just to get events to trigger might not be desired - you may want the current property value to remain, but still want the events to trigger. If you're OK with the workaround, then that's great - less work to do :)

      Delete