Как показать программную клавиатуру на родной активности - PullRequest
11 голосов
/ 03 мая 2011

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

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

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

Вы можете мне помочь?

Ответы [ 3 ]

4 голосов
/ 14 мая 2011

У меня точно такая же проблема.Невозможно отобразить клавиатуру с помощью этого 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();
}
1 голос
/ 19 января 2017

Другой способ - использовать гибридное решение, в котором вы расширяете 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, как это было задумано, и иметь собственный вызов кода в оболочках, тем самым уменьшая сложность синтаксиса на нативной стороне.

0 голосов
/ 30 мая 2012

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

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, который вы хотите получить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...