teclado para google gboard como celular cambiar activar android keyboard

android - para - teclado de google



¿Cómo puedo detectar si el Teclado de software es visible en un dispositivo Android? (22)

¿Hay alguna manera en Android para detectar si el software (también conocido como "suave") del teclado es visible en la pantalla?


Muy fácil

1. Ponga la identificación en su vista de raíz

rootView es solo una vista que apunta a mi vista raíz, en este caso un relative layout :

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/addresses_confirm_root_view" android:background="@color/WHITE_CLR">

2. Inicialice su vista raíz en su Actividad:

RelativeLayout rootView = (RelativeLayout) findViewById(R.id.addresses_confirm_root_view); 3. Detecta si el teclado se abre o cierra usando getViewTreeObserver()

rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { int heightDiff = rootView.getRootView().getHeight() - rootView.getHeight(); if (heightDiff > 100) { Log.e("MyActivity", "keyboard opened"); } else { Log.e("MyActivity", "keyboard closed"); } } });


Aquí hay una solución para saber si el teclado está visible.

  1. Compruebe si hay servicios en ejecución en el sistema usando ActivityManager.getRunningServices (max_count_of_services);
  2. A partir de las instancias de ActivityManager.RunningServiceInfo devueltas, compruebe el valor de clientCount para el servicio de teclado virtual .
  3. El clientCount antes mencionado se incrementará cada vez que se muestre el teclado virtual. Por ejemplo, si clientCount fue inicialmente 1, sería 2 cuando se muestra el teclado.
  4. En el despido del teclado, clientCount disminuye. En este caso, se restablece a 1.

Algunos de los teclados populares tienen ciertas palabras clave en sus classNames:

  1. Google AOSP = IME
  2. Swype = IME
  3. Swiftkey = KeyboardService
  4. Fleksy = teclado
  5. Adaptxt = IME (KPTAdaptxtIME)
  6. Smart = Teclado (SmartKeyboard)

Desde ActivityManager.RunningServiceInfo, verifica los patrones anteriores en ClassNames. Además, el paquete de cliente de ActivityManager.RunningServiceInfo = android, lo que indica que el teclado está vinculado al sistema.

La información mencionada anteriormente podría combinarse para conocer de forma estricta si el teclado virtual está visible.


Creé una clase simple que se puede usar para esto: https://github.com/ravindu1024/android-keyboardlistener . Simplemente cópielo en su proyecto y utilícelo de la siguiente manera:

KeyboardUtils.addKeyboardToggleListener(this, new KeyboardUtils.SoftKeyboardToggleListener() { @Override public void onToggleSoftKeyboard(boolean isVisible) { Log.d("keyboard", "keyboard visible: "+isVisible); } });


Creo que esta es una vieja pregunta, pero hoy encuentro una buena biblioteca para identificar que el teclado está abierto O no. Así que estoy compartiendo aquí.

Tuve un problema similar y encontré una biblioteca para esto, y jugué con eso. Está funcionando como aspectado. Aquí está la Biblioteca de Teclado.


En Android, puedes detectar a través del shell ADB. Escribí y uso este método:

{ JSch jsch = new JSch(); try { Session session = jsch.getSession("<userName>", "<IP>", 22); session.setPassword("<Password>"); Properties config = new Properties(); config.put("StrictHostKeyChecking", "no"); session.setConfig(config); session.connect(); ChannelExec channel = (ChannelExec)session.openChannel("exec"); BufferedReader in = new BufferedReader(new InputStreamReader(channel.getInputStream())); channel.setCommand("C:/Android/android-sdk/platform-tools/adb shell dumpsys window InputMethod | findstr /"mHasSurface/""); channel.connect(); String msg = null; String msg2 = " mHasSurface=true"; while ((msg = in.readLine()) != null) { Boolean isContain = msg.contains(msg2); log.info(isContain); if (isContain){ log.info("Hiding keyboard..."); driver.hideKeyboard(); } else { log.info("No need to hide keyboard."); } } channel.disconnect(); session.disconnect(); } catch (JSchException | IOException | InterruptedException e) { e.printStackTrace(); } } }


En mi caso, solo tenía un EditText para administrar en mi diseño, así que surgió this solución. Funciona bien, básicamente es un EditText personalizado que escucha el enfoque y envía una transmisión local si el foco cambia o si se presiona el botón back / done. Para trabajar necesita colocar una View ficticia en su diseño con android:focusable="true" y android:focusableInTouchMode="true" porque cuando llama a clearFocus() el enfoque se reasignará a la primera vista enfocable. Ejemplo de vista ficticia:

<View android:layout_width="1dp" android:layout_height="1dp" android:focusable="true" android:focusableInTouchMode="true"/>

Infos adicionales

La solución que detecta la diferencia en los cambios de diseño no funciona muy bien porque depende en gran medida de la densidad de la pantalla, ya que 100px puede ser mucho en un dispositivo determinado y nada en otros puede obtener falsos positivos. También diferentes proveedores tienen diferentes teclados.


Esto fue mucho menos complicado para los requisitos que necesitaba. Espero que esto pueda ayudar:

En la actividad principal:

public void dismissKeyboard(){ InputMethodManager imm =(InputMethodManager)this.getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(mSearchBox.getWindowToken(), 0); mKeyboardStatus = false; } public void showKeyboard(){ InputMethodManager imm =(InputMethodManager)this.getSystemService(Context.INPUT_METHOD_SERVICE); imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY); mKeyboardStatus = true; } private boolean isKeyboardActive(){ return mKeyboardStatus; }

El valor booleano de primative predeterminado para mKeyboardStatus se inicializará a falso .

Luego verifique el valor de la siguiente manera y realice una acción si es necesario:

mSearchBox.requestFocus(); if(!isKeyboardActive()){ showKeyboard(); }else{ dismissKeyboard(); }


Esto funciona para mí Quizás esta sea siempre la mejor manera para todas las versiones .

contentView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { Rect r = new Rect(); contentView.getWindowVisibleDisplayFrame(r); int screenHeight = contentView.getRootView().getHeight(); // r.bottom is the position above soft keypad or device button. // if keypad is shown, the r.bottom is smaller than that before. int keypadHeight = screenHeight - r.bottom; Log.d(TAG, "keypadHeight = " + keypadHeight); if (keypadHeight > screenHeight * 0.15) { // 0.15 ratio is perhaps enough to determine keypad height. // keyboard is opened } else { // keyboard is closed } } });


Hay un método directo para descubrir esto. Y, no requiere los cambios de diseño.
Por lo tanto, también funciona en modo inmersivo de pantalla completa.
Pero, desafortunadamente, no funciona en todos los dispositivos. Entonces debes probarlo con tu (s) dispositivo (s).

El truco es que intentas ocultar o mostrar el teclado virtual y capturar el resultado de ese intento.
Si funciona correctamente, entonces el teclado no se muestra u oculta realmente. Solo preguntamos por el estado.

Para mantenerse actualizado, simplemente repita esta operación, por ejemplo, cada 200 milisegundos, usando un controlador.

La implementación a continuación hace solo una comprobación.
Si realiza varias comprobaciones, debe habilitar todas las pruebas (_keyboardVisible).

public interface OnKeyboardShowHide { void onShowKeyboard( Object param ); void onHideKeyboard( Object param ); } private static Handler _keyboardHandler = new Handler(); private boolean _keyboardVisible = false; private OnKeyboardShowHide _keyboardCallback; private Object _keyboardCallbackParam; public void start( OnKeyboardShowHide callback, Object callbackParam ) { _keyboardCallback = callback; _keyboardCallbackParam = callbackParam; // View view = getCurrentFocus(); if (view != null) { InputMethodManager imm = (InputMethodManager) getSystemService( Activity.INPUT_METHOD_SERVICE ); imm.hideSoftInputFromWindow( view.getWindowToken(), InputMethodManager.HIDE_IMPLICIT_ONLY, _keyboardResultReceiver ); imm.showSoftInput( view, InputMethodManager.SHOW_IMPLICIT, _keyboardResultReceiver ); } else // if (_keyboardVisible) { _keyboardVisible = false; _keyboardCallback.onHideKeyboard( _keyboardCallbackParam ); } } private ResultReceiver _keyboardResultReceiver = new ResultReceiver( _keyboardHandler ) { @Override protected void onReceiveResult( int resultCode, Bundle resultData ) { switch (resultCode) { case InputMethodManager.RESULT_SHOWN : case InputMethodManager.RESULT_UNCHANGED_SHOWN : // if (!_keyboardVisible) { _keyboardVisible = true; _keyboardCallback.onShowKeyboard( _keyboardCallbackParam ); } break; case InputMethodManager.RESULT_HIDDEN : case InputMethodManager.RESULT_UNCHANGED_HIDDEN : // if (_keyboardVisible) { _keyboardVisible = false; _keyboardCallback.onHideKeyboard( _keyboardCallbackParam ); } break; } } };


Hice esto configurando un GlobalLayoutListener, de la siguiente manera:

final View activityRootView = findViewById(R.id.activityRoot); activityRootView.getViewTreeObserver().addOnGlobalLayoutListener( new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { int heightView = activityRootView.getHeight(); int widthView = activityRootView.getWidth(); if (1.0 * widthView / heightView > 3) { //Make changes for Keyboard not visible } else { //Make changes for keyboard visible } } });


Hice esto de la siguiente manera, pero solo aparece si su objetivo es cerrar / abrir el teclado.

Ejemplo cercano: (verificando si el teclado ya está cerrado, si no, cerrando)

imm.showSoftInput(etSearch, InputMethodManager.HIDE_IMPLICIT_ONLY, new ResultReceiver(null) { @Override protected void onReceiveResult(int resultCode, Bundle resultData) { super.onReceiveResult(resultCode, resultData); if (resultCode != InputMethodManager.RESULT_UNCHANGED_HIDDEN) imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); } });


La respuesta de @iWantScala es genial, pero no funciona para mí
rootView.getRootView().getHeight() siempre tiene el mismo valor

una forma es definir dos vars

private int maxRootViewHeight = 0; private int currentRootViewHeight = 0;

agregar oyente global

rootView.getViewTreeObserver() .addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { currentRootViewHeight = rootView.getHeight(); if (currentRootViewHeight > maxRootViewHeight) { maxRootViewHeight = currentRootViewHeight; } } });

Entonces revisa

if (currentRootViewHeight >= maxRootViewHeight) { // Keyboard is hidden } else { // Keyboard is shown }

funciona bien


Lo usé como base: http://www.ninthavenue.com.au/how-to-check-if-the-software-keyboard-is-shown-in-android

/** * To capture the result of IMM hide/show soft keyboard */ public class IMMResult extends ResultReceiver { public int result = -1; public IMMResult() { super(null); } @Override public void onReceiveResult(int r, Bundle data) { result = r; } // poll result value for up to 500 milliseconds public int getResult() { try { int sleep = 0; while (result == -1 && sleep < 500) { Thread.sleep(100); sleep += 100; } } catch (InterruptedException e) { Log.e("IMMResult", e.getMessage()); } return result; } }

Luego escribió este método:

public boolean isSoftKeyboardShown(InputMethodManager imm, View v) { IMMResult result = new IMMResult(); int res; imm.showSoftInput(v, 0, result); // if keyboard doesn''t change, handle the keypress res = result.getResult(); if (res == InputMethodManager.RESULT_UNCHANGED_SHOWN || res == InputMethodManager.RESULT_UNCHANGED_HIDDEN) { return true; } else return false; }

A continuación, puede usar esto para probar todos los campos (EditText, AutoCompleteTextView, etc.) que pueden haber abierto un teclado virtual:

InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE); if(isSoftKeyboardShown(imm, editText1) | isSoftKeyboardShown(imm, autocompletetextview1)) //close the softkeyboard imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);

Además, no es una solución ideal, pero hace el trabajo bien.


Mis mejores experiencias fueron hacer mi propio teclado



Pruebe este código, realmente funciona si se muestra KeyboardShown, luego esta función devuelve el valor verdadero ...

private final String TAG = "TextEditor"; private TextView mTextEditor; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_editor); mTextEditor = (TextView) findViewById(R.id.text_editor); mTextEditor.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { isKeyboardShown(mTextEditor.getRootView()); } }); } private boolean isKeyboardShown(View rootView) { /* 128dp = 32dp * 4, minimum button height 32dp and generic 4 rows soft keyboard */ final int SOFT_KEYBOARD_HEIGHT_DP_THRESHOLD = 128; Rect r = new Rect(); rootView.getWindowVisibleDisplayFrame(r); DisplayMetrics dm = rootView.getResources().getDisplayMetrics(); /* heightDiff = rootView height - status bar height (r.top) - visible frame height (r.bottom - r.top) */ int heightDiff = rootView.getBottom() - r.bottom; /* Threshold size: dp to pixels, multiply with display density */ boolean isKeyboardShown = heightDiff > SOFT_KEYBOARD_HEIGHT_DP_THRESHOLD * dm.density; Log.d(TAG, "isKeyboardShown ? " + isKeyboardShown + ", heightDiff:" + heightDiff + ", density:" + dm.density + "root view height:" + rootView.getHeight() + ", rect:" + r); return isKeyboardShown; }


Puede consultar esta respuesta - https://.com/a/24105062/3629912

Funcionó para mí todo el tiempo.

adb shell dumpsys window InputMethod | grep "mHasSurface"

Volverá a ser verdadero, si el teclado del software está visible.



Tuve un problema similar. Necesitaba reaccionar al botón Enter en la pantalla (que ocultaba el teclado). En este caso, puede suscribirse al OnEditorAction de la vista de texto con la que se abrió el teclado: si tiene varios cuadros editables, suscríbase a todos ellos.

En su actividad tiene el control total del teclado, por lo que en ningún momento enfrentará el problema si el teclado está abierto o no, si escucha todos los eventos de apertura y cierre.


a puede estar usando:

@Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); Log.d( getClass().getSimpleName(), String.format("conf: %s", newConfig)); if (newConfig.hardKeyboardHidden != hardKeyboardHidden) { onHardwareKeyboardChange(newConfig.hardKeyboardHidden); hardKeyboardHidden = newConfig.hardKeyboardHidden; } if (newConfig.keyboardHidden != keyboardHidden) { onKeyboardChange(newConfig.keyboardHidden); keyboardHidden = newConfig.hardKeyboardHidden; } } public static final int KEYBOARDHIDDEN_UNDEFINED = 0; public static final int KEYBOARDHIDDEN_NO = 1; public static final int KEYBOARDHIDDEN_YES = 2; public static final int KEYBOARDHIDDEN_SOFT = 3; //todo private void onKeyboardChange(int keyboardHidden) { } //todo private void onHardwareKeyboardChange(int hardKeyboardHidden) { }


prueba esto:

InputMethodManager imm = (InputMethodManager) getActivity() .getSystemService(Context.INPUT_METHOD_SERVICE); if (imm.isAcceptingText()) { writeToLog("Software Keyboard was shown"); } else { writeToLog("Software Keyboard was not shown"); }


final View activityRootView = findViewById(R.id.rootlayout); activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { Rect r = new Rect(); activityRootView.getWindowVisibleDisplayFrame(r); int screenHeight = activityRootView.getRootView().getHeight(); Log.e("screenHeight", String.valueOf(screenHeight)); int heightDiff = screenHeight - (r.bottom - r.top); Log.e("heightDiff", String.valueOf(heightDiff)); boolean visible = heightDiff > screenHeight / 3; Log.e("visible", String.valueOf(visible)); if (visible) { Toast.makeText(LabRegister.this, "I am here 1", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(LabRegister.this, "I am here 2", Toast.LENGTH_SHORT).show(); } } });