在C/C++中接收完整的android unicode输入

前端之家收集整理的这篇文章主要介绍了在C/C++中接收完整的android unicode输入前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
( Android,NDK,C,OpenGL ES)

我需要一种方法可靠地从(软)键盘接收文本输入.
解决方案可以通过Java使用NativeActivity子类或任何有效的方法.
最后我需要输入任何文本,所以我可以用OpenGL自己渲染它

一些背景:
到目前为止,我通过调用showSoftInput或hideSoftInputFromWindow来调用JNI来触发软键盘.这到目前为止从未失败过.
但是,问题是本机活动不会发送所有字符.特别是ASCII范围之外的一些unicode字符,或某些运动软键盘不起作用(AKeyEvent_getKeyCode)

以前可以获取一些其他unicode字符,以便检查KeyEvent.ACTION_MULTIPLE并读取一串字符.
但即使这样也不会再可靠.

到目前为止,我没有找到替代方法.
我尝试以编程方式添加EditText,但从未让它工作.即使尝试添加一个简单的Button也导致OpenGL视图不再被渲染.

在iOS上我通过隐藏编辑框来解决它,我只是激活它以使键盘显示.然后我会读出编辑框并使用字符串在OpenGL中渲染自己.

解决方法

我有同样的问题,我使用’Character’事件解决了它,我将事件与InputEvent分开处理.

问题是:AKeyEvent_getKeyCode不会返回某些软键事件的KeyCode,特别是按住键时扩展的“unicode / latin”字符.这可以防止方法@Shammi和@eozgonul工作,因为在Java端重建的KeyEvent没有足够的信息来获取unicode字符.

另一个问题是在触发dispatchKeyEvent事件之前,在C / Native端排出了InputQueue.这意味着KEYDOWN / KEYUP事件在Java代码可以处理事件之前全部触发. (它们不是交错的).

我的解决方案是通过重写dispatchKeyEvent并将字符发送到Queue< Integer>来捕获Java端的unicode字符. queueLastInputCharacter = new ConcurrentLinkedQueue< Integer>();

  1. // [JAVA]
  2. @Override
  3. public boolean dispatchKeyEvent (KeyEvent event)
  4. {
  5. int MetaState = event.getMetaState();
  6. int unichar = event.getUnicodeChar(MetaState);
  7.  
  8. // We are queuing the Unicode version of the characters for
  9. // sending to the app during processEvents() call.
  10.  
  11. // We Queue the KeyDown and ActionMultiple Event UnicodeCharacters
  12. if(event.getAction()==KeyEvent.ACTION_DOWN){
  13. if(unichar != 0){
  14. queueLastInputCharacter.offer(Integer.valueOf(unichar));
  15. }
  16. else{
  17. unichar = event.getUnicodeChar();
  18.  
  19. if(unichar != 0){
  20. queueLastInputCharacter.offer(Integer.valueOf(unichar));
  21. }
  22. else if (event.getDisplayLabel() != 0){
  23. String aText = new String();
  24. aText = "";
  25. aText += event.getDisplayLabel();
  26. queueLastInputCharacter.offer(Integer.valueOf(Character.codePointAt(aText,0)));
  27. }
  28. else
  29. queueLastInputCharacter.offer(Integer.valueOf(0));
  30. }
  31. }
  32. else if(event.getAction()==KeyEvent.ACTION_MULTIPLE){
  33. unichar = (Character.codePointAt(event.getCharacters(),0));
  34. queueLastInputCharacter.offer(Integer.valueOf(unichar));
  35. }
  36.  
  37.  
  38. return super.dispatchKeyEvent(event);
  39. }

并发队列将让线程一起玩得很好.

我有一个Java方法返回最后一个输入字符:

  1. // [JAVA]
  2. public int getLastUnicodeChar(){
  3. if(!queueLastInputCharacter.isEmpty())
  4. return queueLastInputCharacter.poll().intValue();
  5. return 0;
  6. }

在我的looper代码结束时,我进行了额外的检查以查看队列是否保留了任何unicode字符:

  1. // [C++]
  2. int ident;
  3. int events;
  4. struct android_poll_source* source;
  5.  
  6. // If not rendering,we will block 250ms waiting for events.
  7. // If animating,we loop until all events are read,then continue
  8. // to draw the next frame of animation.
  9. while ((ident = ALooper_pollAll(((nv_app_status_focused(_lpApp)) ? 1 : 250),NULL,&events,(void**)&source)) >= 0)
  10. {
  11. // Process this event.
  12. if (source != NULL)
  13. source->process(_lpApp,source);
  14.  
  15. // Check if we are exiting. If so,dump out
  16. if (!nv_app_status_running(_lpApp))
  17. return;
  18. }
  19.  
  20. static int modtime = 10; // let's not run on every call
  21. if(--modtime == 0) {
  22. long uniChar = androidUnicodeCharFromKeyEvent();
  23. while (uniChar != 0) {
  24. KEvent kCharEvent; // Game engine event
  25. kCharEvent.ptkKey = K_VK_ERROR;
  26. kCharEvent.unicodeChar = uniChar;
  27. kCharEvent.character = uniChar;
  28.  
  29. /* Send unicode char */
  30. kCharEvent.type = K_EVENT_UNICHAR;
  31. _lpPortableHandler(&kCharEvent);
  32.  
  33. if (kCharEvent.character < 127) {
  34. /* Send ascii char for source compatibility as well */
  35. kCharEvent.type = K_EVENT_CHAR;
  36. _lpPortableHandler(&kCharEvent);
  37. }
  38.  
  39. uniChar = androidUnicodeCharFromKeyEvent();
  40. }
  41. modtime = 10;
  42. }

androidUnicodeCharFromKeyEvent函数与@Shammi的GetStringFromAInputEvent方法非常相似,只使用CallIntMethod来返回jint.

笔记
这确实需要修改引擎以处理与Key事件分开的字符事件. Android仍然有像AKEYCODE_BACK或AKEYCODE_ENTER这样的密钥代码,它们不是字符事件,仍然需要处理(并且可以在主输入循环器上处理).

编辑框,控制台等…可以修改期望用户输入的内容以接收构建字符串的单独字符事件.如果您在多个平台上工作,那么除了普通的键输入事件之外,您还需要生成这些新的字符事件.

猜你在找的C&C++相关文章