2011-12-22 8 views
7

Próbuję wykryć wysokość klawiatury wirtualnej w systemie Android.Jak wysłać zdarzenie wskaźnika w systemie Android?

znalazłem podobny temat: Get the height of virtual keyboard in Android

Wydaje się, że autor znalazł sposób na wykrycie wysokość:

znalazłem sposób je zdobyć. Po żądaniu otwarcia wirtualnej klawiatury, I wysyłam zdarzenie wskaźnika, które generuję. ich współrzędna y zaczyna się od wysokości urządzenia i zmniejsza się.

Nie rozumiem, jak to zrobić.

Odpowiedz

3

będę przy użyciu kodu podanego w linku, który pisał:

// Declare Variables 

int softkeyboard_height = 0; 
boolean calculated_keyboard_height; 
Instrumentation instrumentation; 

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

mainScreenView jest twój widok bazowy, widok Twojej aktywności za. m (ACTION_DOWN) i m1 (ACTION_UP) to zdarzenia dotykowe, które są wywoływane za pomocą Instrumentation#sendPointerSync(MotionEvent). Logika jest taka, że ​​MotionEvent wysyłane do miejsca, gdzie klawiatura jest wyświetlana spowoduje następujące SecurityException:

java.lang.SecurityException: Wstrzykiwanie do innej aplikacji wymaga zgody INJECT_EVENTS

Więc zaczynamy w dolnej części ekranu i podążaj w górę (zmniejszając liczbę y) na każdej iteracji pętli. W przypadku pewnej liczby iteracji otrzymamy SecurityException (który będziemy przechwytywać): oznacza to, że MotionEvent dzieje się za pomocą klawiatury. Moment y dostaje wystarczająco małe (kiedy jest tuż nad klawiaturą), będziemy wyrwać się z pętli i obliczyć wysokość klawiatura jest przy użyciu:

softkeyboard_height = mainScreenView.getHeight() - y; 

Kod:

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):

Wysłanie zdarzenia wskaźnika. Zakończył się w pewnym momencie po tym, jak odbiorca powrócił z przetwarzania zdarzenia, chociaż może on nie mieć kompletnie zakończonej reakcji ze zdarzenia - na przykład, jeśli w wyniku tego musi zaktualizować swój wyświetlacz, może nadal znajdować się w proces robienia tego.

+0

Czy to jest publiczny interfejs API? Nie mogę znaleźć dokumentacji dotyczącej "INTERNAL_POINTER_META_STATE". – rid

+0

@rid Przepraszam za to. 'INTERNAL_POINTER_META_STATE' jest stałą całkowitą. Dla celów pytania działałaby jakakolwiek wartość całkowita. Edytowałem powyższy kod. Dziękuję za wskazanie. – Vikram

+0

Mimo to, czy korzystanie z tej funkcji jest bezpieczne, bez możliwości zniknięcia funkcjonalności w przyszłej wersji Androida? Czy to "1" gwarantuje zawsze to samo? Czy Google oficjalnie dokumentuje go oficjalnie? Czy możesz polegać na tym bez obawy o tworzenie łamliwego kodu? – rid

1

Użyj OnGlobalLayoutListener, działa idealnie dla mnie.