Как показать на клавиатуре мягкую клавиатуру

Когда я пытаюсь использовать ANativeActivity_showSoftInput(), он не вызывает мягкую клавиатуру.

Я попытался использовать ANativeActivity_showSoftInput(engine->app->activity, ANATIVEACTIVITY_SHOW_SOFT_INPUT_FORCED) и ANativeActivity_showSoftInput(engine->app->activity, ANATIVEACTIVITY_SHOW_SOFT_INPUT_IMPLICIT), чтобы показать softinput, но также не удалось.

Я прочитал исходный код и нашел после запуска nativeActivity, NativeContentView(extend View), и при вызове ANativeActivity_showSoftInput он будет вызывать showSoftInput() в java-стороне. Я думаю, может быть, softkeyboard не включен.

Можете ли вы мне помочь?

Ответ 1

У меня точно такая же проблема. Невозможно показать Клавиатуру с помощью этого API.

Единственное, что я нашел, это использовать JNI, но, конечно, я не удовлетворен этим решением:

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();
}

Ответ 2

Другим способом является гибридное решение, в котором вы расширяете NativeActivity в java и имеете вспомогательные функции для отображения и скрытия клавиатуры.

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 );
    }
}

И на родной стороне...

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();
    }
}

Это позволяет вам обрабатывать специфические вещи Android в java, поскольку это было предназначено, и иметь встроенный вызов кода в оболочку, что уменьшает сложность синтаксиса на родной стороне.

Ответ 3

У меня было много проблем с попыткой закрыть мягкую клавиатуру, когда вид изменился, пока я не понял, что мне нужно было удалить его из вида, который его назвал:

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

Также существует метод showSoftInput, который, вероятно, должен работать (при условии, что он делает то, что имя метода говорит, что он это делает) аналогичным образом, где ему нужно представление, чтобы привязать себя к:

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

В настоящий момент я не могу проверить это сам, но я решил, что он сможет вам помочь и будет стоить того. Просто убедитесь, что "editText" связан с EditText, который вы хотите получить.