Delphi Android 10.3.3 上的 Return 键没有 OnKeyDown 事件

No OnKeyDown event for Return key on Delphi Android 10.3.3

我正在从 Delphi 10.2.3 升级到 10.3.3。我的 android 应用程序现在不会从 Return 键的虚拟键盘生成 OnKeyDown 事件。我已经使用一个非常基本的新创建项目确认了这一点,因此它似乎与 10.2.3 的转换无关。

如有任何想法,我们将不胜感激。

embarcadero 的 QA 回复如下:

“根据本文档 - Handle keyboard actions or this - KeyEvent :

在使用 KeyEvent class 和相关 API 处理键盘事件时,您应该期望此类键盘事件仅来自硬件键盘。您永远不应依赖于接收软输入法(屏幕键盘)上任何键的键事件。

我认为使用文本更改时触发的方法足以解决此问题...

我认为这个 Whosebug question and this Blogpost 可能有用。 “

提供的解决方案包括向 JFMXTextEditorProxy 添加一个 TextListener,而后一个接口已从 delphi 10.3 中消失。我目前正在尝试在 10.3 中实现等效的功能,但希望得到任何指导。顺便说一句:其他人会有不同的目标,但就我而言,我只想看到 return 键。

更新:最初这被认为是一个错误。然而,embarcadero 的 QA 认为它不是,也不应该依赖虚拟键盘来触发键盘事件。但他们没有提供其他可行的选择。他们引用的博客post不适合10.3,而且好像永远也看不到return键

我偶然发现了一种解决方法,它似乎有效,但它也可能容易受到未来变化的影响。

如果将 Tedit 的 ReturnKeyType 更改为任何值 GoSearchSend,onkeydown 事件将为 return 键触发。 另一种选择是使用 OnChange 事件。这不会触发 return 键,当 Tedit 设置为 Default ReturnKeyType 时,但当设置为上述任何值(加上 Next 也)时,它会触发。 ReturnKeyType 在设计时可用,也可以在代码中更改,例如:

  edit1.ReturnKeyType := TReturnKeyType.Go;

如果真的很绝望,我观察到如果编辑的内容确实发生了变化并且使用 Android "back" 按钮关闭虚拟键盘,OnChange 事件将会触发。

解决本次讨论中出现的各种问题:

  1. RSP-27496 已重新打开
  2. 您可以通过编辑 C:\Program Files (x86)\Embarcadero\Studio.0\source\rtl\androiddex\java\fmx\src\com\embarcadero\firemonkey\text\FMXEditText.java 并重建所需的 Java 文件来解决此问题通过 Delphi Android 个应用程序。这允许 Return 键根据需要获取 OnKeyDownOnKeyUp 事件,而无需使用 TomB 的解决方法。

要对 FMXEditText.java

进行哪些编辑

在方法 onEditorAction 中,它只有一个 if 语句,在 if 和 else 分支中都有代码,将代码从 else 分支中取出并使其成为无条件的。

换句话说,它说(我发布了一个代表性代码片段而不是粘贴实际代码以避免被指责做 'naughty' 事情):

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

改成:

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

如何重建 Java RTL 文件

这部分有点复杂,无法在此处详细介绍,但您需要的是一个命令脚本,它基本上可以为您完成这项工作。为了修复 10.3.0 中的 Java 问题,我在 a blog post here in amongst discussion of the issue being fixed, and for 10.3.3 a post solely for how to rebuild the Java files can be found here.

上提供了一个命令脚本

但是,为了避免有关外部链接解决方案的评论不当,因为这些链接可能会随着时间的推移而消失,这里是完整的命令脚本。检查所有插入变量的路径是否正确,将脚本存储在名为 BuildFMX.cmd 的文件中,运行 管理命令提示符并从那里调用脚本:

@echo off
cls

rem Android RTL Java files rebuilder for RAD Studio 10.3.3

setlocal enabledelayedexpansion

rem Set environment variables
rem *NOTE*: check these folders match your setup

set EMBT=Embarcadero\Studio.0
set BDS=%ProgramFiles(x86)%\%EMBT%
set JAVA_PATH=%ProgramFiles%\Java\jdk1.8.0_60\bin
rem This is the default path for the Android SDK when installed from the .iso installer
set SDK_PATH=%PUBLIC%\Documents\%EMBT%\PlatformSDKs\android-sdk-windows
if not exist "%SDK_PATH%\" (
  rem This is the default path for the Android SDK when installed from the web install (aka ESD install)
  set SDK_PATH=%PUBLIC%\Documents\%EMBT%\CatalogRepository\AndroidSDK-2525_20.0.36039.7899
)

rem Set more environment variables based on those above

set DX_PATH=%SDK_PATH%\build-tools.0.2
set ANDROID_JAR=%SDK_PATH%\platforms\android-26\android.jar
set BDS_LIB=%BDS%\lib
set BDS_DEBUG_LIB=%BDS%\lib\android\debug
set BDS_RELEASE_LIB=%BDS%\lib\android\release
set FMX_SRC_PATH=%BDS%\source\rtl\androiddex\java\fmx
set CLASS_PATH=%ANDROID_JAR%
set CLASS_PATH=%CLASS_PATH%;%BDS_DEBUG_LIB%\android-support-v4.jar
set CLASS_PATH=%CLASS_PATH%;%BDS_DEBUG_LIB%\cloud-messaging.jar
set CLASS_PATH=%CLASS_PATH%;%BDS_DEBUG_LIB%\com-google-android-gms.play-services-base.16.0.1.jar
set CLASS_PATH=%CLASS_PATH%;%BDS_DEBUG_LIB%\com-google-android-gms.play-services-maps.16.1.0.jar
set CLASS_PATH=%CLASS_PATH%;%BDS_DEBUG_LIB%\debug\com-google-android-gms.play-services-ads.17.2.0.jar
rem For adListener
set CLASS_PATH=%CLASS_PATH%;%BDS_DEBUG_LIB%\com-google-android-gms.play-services-ads-lite.17.2.0.jar
rem For AbstractSafeParcelable
set CLASS_PATH=%CLASS_PATH%;%BDS_DEBUG_LIB%\com-google-android-gms.play-services-basement.16.2.0.jar
rem For ReflectedParcelable
set CLASS_PATH=%CLASS_PATH%;%BDS_DEBUG_LIB%\com-google-android-gms.play-services-basement.16.2.0.jar

echo.
echo Checking environment variables

if not exist "%BDS%\" (
  echo Path used to set BDS environment variable does not exist^^! Is RAD Studio installed elsewhere?
  goto :Error
)

if not exist "%JAVA_PATH%\" (
  echo Path used to set JAVA_PATH environment variable does not exist^^! Is the JDK installed elsewhere?
  goto :Error
)

if not exist "%SDK_PATH%\" (
  echo Path used to set SDK_PATH environment variable does not exist^^! Is the Android SDK installed elsewhere?
  goto :Error
)

if not exist "%ANDROID_JAR%" (
  echo Path used to set ANDROID_JAR environment variable does not exist^^! Is your android.jar in a different platform folder?
  goto :Error
)

echo.
echo Changing to the FMX source folder
echo.

pushd %FMX_SRC_PATH%

echo Getting fully qualified list of all Java source file we need to rebuild
echo.

if not exist bin\classes mkdir bin\classes
if not exist bin\debug mkdir bin\debug
if not exist bin\release mkdir bin\release
dir src\android\bluetooth\*.java /s /b > JavaSources.txt
dir src\android\telephony\*.java /s /b >> JavaSources.txt
dir src\com\*.java /s /b >> JavaSources.txt

echo Ensuring FMX source path ends in a '\'
echo.

set LAST_CHAR=%FMX_SRC_PATH:~-1%
if not "%LAST_CHAR%"=="\" set FMX_SRC_PATH=%FMX_SRC_PATH%\

echo Making Java source file paths relative to current directory
echo.

if exist JavaSources2.txt del JavaSources2.txt
for /F "tokens=*" %%A in (JavaSources.txt) do (
  set STR=%%A
  set "STR=!STR:%FMX_SRC_PATH%=!"
  echo !STR!>>JavaSources2.txt
)

echo Compiling all the FMX Java code into class files with debug info
echo.

"%JAVA_PATH%"\javac -g -d bin\classes -classpath "%CLASS_PATH%" -encoding UTF-8 -g @JavaSources2.txt
if errorlevel 1 (
  echo.
  echo Problem encountered during Java compilation
  goto :Error
)

echo.
echo Creating jar containing the new compiled FMX Java classes with debug info
echo.

"%JAVA_PATH%"\jar cf bin\debug\fmx.jar -C bin\classes .
if errorlevel 1 (
  echo.
  echo Problem encountered during Java archiving
  goto :Error
)

echo Creating DEX jar containing the new compiled FMX Java classes with debug info
echo.

call %DX_PATH%\dx --dex --output=bin\debug\fmx.dex.jar --positions=lines bin\debug\fmx.jar
if errorlevel 1 (
  echo.
  echo Problem encountered during DEXing
  goto :Error
)

echo Compiling all the FMX Java code into class files without debug info
echo.

"%JAVA_PATH%"\javac -g:none -d bin\classes -classpath "%CLASS_PATH%" -encoding UTF-8 @JavaSources2.txt
if errorlevel 1 (
  echo.
  echo Problem encountered during Java compilation
  goto :Error
)

echo.
echo Creating jar containing the new compiled FMX Java classes without debug info
echo.

"%JAVA_PATH%"\jar cf bin\release\fmx.jar -C bin\classes .
if errorlevel 1 (
  echo.
  echo Problem encountered during Java archiving
  goto :Error
)

echo Creating DEX jar containing the new compiled FMX Java classes without debug info
echo.

call %DX_PATH%\dx --dex --output=bin\release\fmx.dex.jar --positions=lines bin\release\fmx.jar
if errorlevel 1 (
  echo.
  echo Problem encountered during DEXing
  goto :Error
)

copy bin\debug\* "%BDS_DEBUG_LIB%"
copy bin\release\* "%BDS_RELEASE_LIB%"

echo Tidying up...
echo.
if exist JavaSources.txt del JavaSources.txt
if exist JavaSources2.txt del JavaSources2.txt
rd /s /q bin

goto :End

:Error
echo.
echo Sorry, we had a problem :(
echo.

:End

echo Changing back to the folder we started in

popd

endlocal