使用android NativeActivity时从SoftInput接收所有unicode字符

Sca*_*cam 5 c++ java unicode android android-ndk

我有一个 OpenGL 应用程序,它使用NativeActivity. 当我询问用户姓名时,我通过JNI调用一个java方法为我打开一个软件键盘。游戏在 OpenGL 上下文中显示了它自己的原生文本输入对话框。所有 unicode 字符都应该在名称中可用。

public static void JNI_keyboardShow() {
    InputMethodManager imm = (InputMethodManager)Main.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.showSoftInput(m_window.getDecorView(), InputMethodManager.SHOW_IMPLICIT);
}
Run Code Online (Sandbox Code Playgroud)

我的 java 类扩展,KeyEvent.Callback所以我通过覆盖onKeyDown(int keyCode, KeyEvent event)onKeyMultiple(int keyCode, int count, KeyEvent event)方法接收键盘输入。然后我通过 JNI 将接收到的输入传递给我的 C++ 应用程序。

我的问题是在方法中处理非 ascii unicode 字符onKeyMultiple。它看起来像这样:

@Override
public boolean onKeyMultiple (int keyCode, int count, KeyEvent event) {
    int unicode = event.getUnicodeChar();
    Log.e(TAG, "Unicode: " + unicode);

    String text = null;
    if(event.getAction() == KeyEvent.ACTION_MULTIPLE && keyCode == KeyEvent.KEYCODE_UNKNOWN) {
        text = event.getCharacters();
    }

    Log.e(TAG, "Text: " + text);
    if(text != null) {
        //call native function and pass string to it
        nativeOnKeyDown(text);
    }
    return true;
} 
Run Code Online (Sandbox Code Playgroud)

例如,当我在键盘上输入“笑脸”字符时,文本总是被解释为“白色垂直矩形” ?——它应该显示为. 当我在 Android Studio 的调试器中检查字符串的内容时,它甚至显示为一个矩形。

如果我将文本解析为字节,text.GetBytes(Charset.forName("UTF-8"))我会看到字节表示因不同的 unicode 字符而异。但是,如果我将生成的字节数组传递给 C++ 并将其解析回 C++ 字符串,结果是相同的。unicode 字符显示为垃圾。

event.getUnicodeChar()在这些情况下,该方法始终返回 0。

我的问题是,如何从软键盘接收所有键盘按键?我真的不在乎它是如何完成的,只关心我的 C++ 字符串接收正确的 unicode 字符,然后我可以将它们呈现到屏幕上。

在 C/C++ 中接收完整的 android unicode 输入几乎(但不完全)相同的问题。不同之处在于我想在 Java 端处理键盘输入,并且只将结果字符发送回 C++ 端。答案中给出的代码也面临同样的问题:并非所有键盘输入都会产生正确的 unicode 字符。

android - 获得软键盘按键也讨论了这一点。它警告说,官方 Android 页面说你永远不应该依赖接收软输入法(屏幕键盘)上任何键的键事件。建议使用TextWatcher界面观察软键盘上按下的字符。如果这是要走的路,我想得到一些指导,如何在我的类中实现这个扩展NativeActivity. 我在应用程序中没有任何可编辑的文本字段,只有一个 OpenGL 窗口。

例如,是否可以在我的 OpenGL 上下文之上放置一些透明的窗口/视图/对话框,并以这种方式从软件键盘获取正确的 unicode 字符?

Sca*_*cam 1

这似乎是 Android Studio 的问题,它无法在其调试控制台或调试器中渲染 UTF-8 字符。如果我从命令行启动 adb 日志记录,日志中会出现正确的 UTF-8 字符。

就像我在问题中所说的那样,字节表示因不同的 unicode 字符而异。这才是最重要的。如果将字符串传递给 C++(作为字节数组或字符串),则所有字符都正确存在。

我还更改了程序来实现TextWatcher接口而不是KeyEvent.Callback,但这主要是因为官方 Android 文档建议这样做。但对于这个问题,使用哪个接口/类来读取软件键盘并不重要。