2011-12-22 5 views
7

Estoy intentando detectar la altura del teclado virtual en Android.Cómo enviar un evento de puntero en Android

me encontré con un tema similar: Get the height of virtual keyboard in Android

Al parecer, el autor encontró una manera de detectar la altura:

he encontrado una manera de conseguirlo. Después de que solicite abrir el teclado virtual, I envío el evento del puntero que genero. su coordenada y comienza desde altura del dispositivo y disminuye.

No entiendo cómo hacerlo.

Respuesta

3

voy a estar utilizando el código proporcionado en el vínculo que has publicado:

// Declare Variables 

int softkeyboard_height = 0; 
boolean calculated_keyboard_height; 
Instrumentation instrumentation; 

// Initialize instrumentation sometime before starting the thread 
instrumentation = new Instrumentation(); 

mainScreenView es su vista base, la vista de su actividad. m (ACTION_DOWN) y m1 (ACTION_UP) son eventos táctiles que se envían utilizando Instrumentation#sendPointerSync(MotionEvent). La lógica es que un MotionEvent enviado a donde el teclado se está mostrando hará que el siguiente SecurityException:

java.lang.SecurityException: La inyección a otra aplicación requiere el permiso INJECT_EVENTS

Por lo tanto, comenzamos en la parte inferior de la pantalla y hacer nuestro camino hacia arriba (disminuyendo y) en cada iteración del ciclo. Para cierto número de iteraciones, obtendremos una SecurityException (que captaremos): esto implicaría que MotionEvent está sucediendo a través del teclado. En el momento en y consigue bastante pequeña (cuando su justo encima del teclado), vamos a romper fuera del circuito y calculamos la altura del teclado usando:

softkeyboard_height = mainScreenView.getHeight() - y; 

Código:

Thread t = new Thread(){ 
     public void run() { 
      int y = mainScreenView.getHeight()-2; 
      int x = 10; 
      int counter = 0; 
      int height = y; 
      while (true){ 
       final MotionEvent m = MotionEvent.obtain(
         SystemClock.uptimeMillis(), 
         SystemClock.uptimeMillis(), 
         MotionEvent.ACTION_DOWN, 
         x, 
         y, 
         1); 
       final MotionEvent m1 = MotionEvent.obtain(
         SystemClock.uptimeMillis(), 
         SystemClock.uptimeMillis(), 
         MotionEvent.ACTION_UP, 
         x, 
         y, 
         1); 
       boolean pointer_on_softkeyboard = false; 
       try { 
        instrumentation.sendPointerSync(m); 
        instrumentation.sendPointerSync(m1); 
       } catch (SecurityException e) { 
        pointer_on_softkeyboard = true; 
       } 
       if (!pointer_on_softkeyboard){ 
        if (y == height){ 
         if (counter++ < 100){ 
          Thread.yield(); 
          continue; 
         } 
        } else if (y > 0){ 
         softkeyboard_height = mainScreenView.getHeight() - y; 
         Log.i("", "Soft Keyboard's height is: " + softkeyboard_height); 
        } 
        break; 
       } 
       y--; 

      } 
      if (softkeyboard_height > 0){ 
       // it is calculated and saved in softkeyboard_height 
      } else { 
       calculated_keyboard_height = false; 
      } 
     } 
    }; 
    t.start(); 

Instrumentation#sendPointerSync(MotionEvent):

Despachar un evento de puntero. Finalizado en algún momento después de que el destinatario haya regresado de su procesamiento de eventos, aunque puede no haber terminado reaccionando desde el evento; por ejemplo, si necesita actualizar su pantalla como resultado, aún puede estar en el proceso de hacer eso.

+0

¿Esto es una API pública? No puedo encontrar documentación sobre 'INTERNAL_POINTER_META_STATE'. – rid

+0

@rid Disculpa por eso. 'INTERNAL_POINTER_META_STATE' es una constante entera. Para el propósito de la pregunta, usar cualquier valor entero funcionaría. He editado el código de arriba. Gracias por mencionarlo. – Vikram

+0

Aún así, ¿es seguro usar esto sin que la funcionalidad tenga la posibilidad de desaparecer en ninguna versión futura de Android? ¿Ese '1' garantiza que siempre será el mismo? ¿Está documentado oficialmente en Google por Google? ¿Puedes confiar en esto sin temor a producir código frágil? – rid

1

Usa OnGlobalLayoutListener, funciona perfectamente para mí.

Cuestiones relacionadas