2011-05-03 17 views
11

Cuando intento utilizar ANativeActivity_showSoftInput(), no aparece el teclado virtual.Cómo mostrar el teclado virtual en la actividad nativa

He intentado usar ANativeActivity_showSoftInput(engine->app->activity, ANATIVEACTIVITY_SHOW_SOFT_INPUT_FORCED) y ANativeActivity_showSoftInput(engine->app->activity, ANATIVEACTIVITY_SHOW_SOFT_INPUT_IMPLICIT) para mostrar softinput, pero también ha fallado.

que leer el código fuente, y me encontré después de la puesta nativeActivity, NativeContentView(extend View) se creará, y cuando la llamada ANativeActivity_showSoftInput, se llamará en showSoftInput() lado de Java. Creo que tal vez el teclado no está encendido.

¿Me puede ayudar?

+0

publique exactamente cómo está llamando 'ANativeActivity_showSoftInput()' y más detalles sobre el problema que está teniendo como resultado de la llamada. –

+0

Probé ANativeActivity_showSoftInput (engine-> app-> activity, ANATIVEACTIVITY_SHOW_SOFT_INPUT_FORCED) y ANativeActivity_showSoftInput (engine-> app-> activity, ANATIVEACTIVITY_SHOW_SOFT_INPUT_IMPLICIT) para mostrar softinput, pero falló. Leí el código fuente, encontré después de iniciar la actividad nativa, NativeContentView (ampliar vista) se creará, y cuando llame a ANativeActivity_showSoftInput, llamará a showSoftInput() en java. Creo que tal vez el teclado no está encendido. ¿Y puedes ayudarme? – Miles

+0

@Mike Pennington, por favor, ayúdenme – Miles

Respuesta

4

Tengo exactamente el mismo problema. No hay forma de mostrar el teclado usando esta API.

La única manera que encontré fue utilizar JNI pero por supuesto no estoy satisfecho con la solución:

android_app* mApplication; 

... 

void displayKeyboard(bool pShow) { 
    // Attaches the current thread to the JVM. 
    jint lResult; 
    jint lFlags = 0; 

    JavaVM* lJavaVM = mApplication->activity->vm; 
    JNIEnv* lJNIEnv = mApplication->activity->env; 

    JavaVMAttachArgs lJavaVMAttachArgs; 
    lJavaVMAttachArgs.version = JNI_VERSION_1_6; 
    lJavaVMAttachArgs.name = "NativeThread"; 
    lJavaVMAttachArgs.group = NULL; 

    lResult=lJavaVM->AttachCurrentThread(&lJNIEnv, &lJavaVMAttachArgs); 
    if (lResult == JNI_ERR) { 
     return; 
    } 

    // Retrieves NativeActivity. 
    jobject lNativeActivity = mApplication->activity->clazz; 
    jclass ClassNativeActivity = lJNIEnv->GetObjectClass(lNativeActivity); 

    // Retrieves Context.INPUT_METHOD_SERVICE. 
    jclass ClassContext = lJNIEnv->FindClass("android/content/Context"); 
    jfieldID FieldINPUT_METHOD_SERVICE = 
     lJNIEnv->GetStaticFieldID(ClassContext, 
      "INPUT_METHOD_SERVICE", "Ljava/lang/String;"); 
    jobject INPUT_METHOD_SERVICE = 
     lJNIEnv->GetStaticObjectField(ClassContext, 
      FieldINPUT_METHOD_SERVICE); 
    jniCheck(INPUT_METHOD_SERVICE); 

    // Runs getSystemService(Context.INPUT_METHOD_SERVICE). 
    jclass ClassInputMethodManager = lJNIEnv->FindClass(
     "android/view/inputmethod/InputMethodManager"); 
    jmethodID MethodGetSystemService = lJNIEnv->GetMethodID(
     ClassNativeActivity, "getSystemService", 
     "(Ljava/lang/String;)Ljava/lang/Object;"); 
    jobject lInputMethodManager = lJNIEnv->CallObjectMethod(
     lNativeActivity, MethodGetSystemService, 
     INPUT_METHOD_SERVICE); 

    // Runs getWindow().getDecorView(). 
    jmethodID MethodGetWindow = lJNIEnv->GetMethodID(
     ClassNativeActivity, "getWindow", 
     "()Landroid/view/Window;"); 
    jobject lWindow = lJNIEnv->CallObjectMethod(lNativeActivity, 
     MethodGetWindow); 
    jclass ClassWindow = lJNIEnv->FindClass(
     "android/view/Window"); 
    jmethodID MethodGetDecorView = lJNIEnv->GetMethodID(
     ClassWindow, "getDecorView", "()Landroid/view/View;"); 
    jobject lDecorView = lJNIEnv->CallObjectMethod(lWindow, 
     MethodGetDecorView); 

    if (pShow) { 
     // Runs lInputMethodManager.showSoftInput(...). 
     jmethodID MethodShowSoftInput = lJNIEnv->GetMethodID(
      ClassInputMethodManager, "showSoftInput", 
      "(Landroid/view/View;I)Z"); 
     jboolean lResult = lJNIEnv->CallBooleanMethod(
      lInputMethodManager, MethodShowSoftInput, 
      lDecorView, lFlags); 
    } else { 
     // Runs lWindow.getViewToken() 
     jclass ClassView = lJNIEnv->FindClass(
      "android/view/View"); 
     jmethodID MethodGetWindowToken = lJNIEnv->GetMethodID(
      ClassView, "getWindowToken", "()Landroid/os/IBinder;"); 
     jobject lBinder = lJNIEnv->CallObjectMethod(lDecorView, 
      MethodGetWindowToken); 

     // lInputMethodManager.hideSoftInput(...). 
     jmethodID MethodHideSoftInput = lJNIEnv->GetMethodID(
      ClassInputMethodManager, "hideSoftInputFromWindow", 
      "(Landroid/os/IBinder;I)Z"); 
     jboolean lRes = lJNIEnv->CallBooleanMethod(
      lInputMethodManager, MethodHideSoftInput, 
      lBinder, lFlags); 
    } 

    // Finished with the JVM. 
    lJavaVM->DetachCurrentThread(); 
} 
0

que tenía un montón de problemas tratando de cerrar el teclado en pantalla cuando la vista cambia, hasta que se dio cuenta de que tenía que sacarlo específicamente de la opinión de que lo llamó:

InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); 
      imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); 

también hay un método showSoftInput que probablemente debería trabajar (suponiendo que hace lo que el nombre del método dice que lo hace) de una manera similar, en el que tiene una vista para anclarse a:

InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); 
      imm.showSoftInput(editText.getWindowToken(), 0); 

Realmente no puedo probar esto por el momento, pero pensé que podría ser capaz de ayudarte y valdría la pena intentarlo. Solo asegúrate de que "editText" esté vinculado al EditText del que deseas recibir la entrada.

1

Otra forma es ir con una solución híbrida donde extender NativeActivity en java y tener funciones de ayuda para mostrar y ocultar el teclado.

import android.view.inputmethod.InputMethodManager; 
import android.content.Context; 

public class MyNativeActivity extends android.app.NativeActivity 
{ 
    public void showKeyboard() 
    { 
     InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); 
     imm.showSoftInput(this.getWindow().getDecorView(), InputMethodManager.SHOW_FORCED); 
    } 

    public void hideKeyboard() 
    { 
     InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); 
     imm.hideSoftInputFromWindow(this.getWindow().getDecorView().getWindowToken(), 0); 
    } 
} 

Y en el lado nativo ...

void DisplayKeyboard(bool bShow) 
{ 
    // Attaches the current thread to the JVM. 
    JavaVM* pJavaVM = m_pNativeActivity->vm; 
    JNIEnv* pJNIEnv = m_pNativeActivity->env; 

    JavaVMAttachArgs javaVMAttachArgs; 
    javaVMAttachArgs.version = JNI_VERSION_1_6; 
    javaVMAttachArgs.name = "NativeThread"; 
    javaVMAttachArgs.group = NULL; 

    jint nResult = pJavaVM->AttachCurrentThread(&pJNIEnv, &javaVMAttachArgs); 
    if (nResult != JNI_ERR) 
    { 
     // Retrieves NativeActivity. 
     jobject nativeActivity = m_pNativeActivity->clazz; 
     jclass ClassNativeActivity = pJNIEnv->GetObjectClass(nativeActivity); 

     if (bShow) 
     { 
      jmethodID MethodShowKeyboard = pJNIEnv->GetMethodID(ClassNativeActivity, "showKeyboard", "()V"); 
      pJNIEnv->CallVoidMethod(nativeActivity, MethodShowKeyboard); 
     } 
     else 
     { 
      jmethodID MethodHideKeyboard = pJNIEnv->GetMethodID(ClassNativeActivity, "hideKeyboard", "()V"); 
      pJNIEnv->CallVoidMethod(nativeActivity, MethodHideKeyboard); 
     } 

     // Finished with the JVM. 
     pJavaVM->DetachCurrentThread(); 
    } 
} 

Esto le permite hacer frente a la materia específica de Android en Java, como estaba previsto y tienen el llamado código nativo en envolturas, reduciendo así el complejidad en sintaxis en el lado nativo.

Cuestiones relacionadas