2011-12-22 2 views
7

Я пытаюсь определить высоту виртуальной клавиатуры в Android.Как отправить событие указателя в Android

я нашел подобную тему: Get the height of virtual keyboard in Android

Кажется, автор нашел способ определить высоту:

Я нашел способ, чтобы получить его. После запроса виртуальной клавиатуры I отправьте событие указателя, которое я создаю. их координата y начинается с высоты устройства и уменьшается.

Я не понимаю, как это сделать.

ответ

3

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

// Declare Variables 

int softkeyboard_height = 0; 
boolean calculated_keyboard_height; 
Instrumentation instrumentation; 

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

mainScreenView ваша база вида, вид Вашу деятельность в. m (ACTION_DOWN) и m1 (ACTION_UP) - это события касания, которые отправляются с использованием Instrumentation#sendPointerSync(MotionEvent). Логика в том, что MotionEvent отправляется туда, где клавиатура отображается вызовет следующий SecurityException:

java.lang.SecurityException: Инъекционное другому приложению требуется разрешение INJECT_EVENTS

Итак, мы начинаем в нижней части экрана и продвигайтесь вверх (путем уменьшения y) на каждой итерации цикла. Для определенного количества итераций мы получим SecurityException (которое мы поймаем): это будет означать, что MotionEvent происходит через клавиатуру. Момент y получает достаточно мал (когда его прямо над клавиатурой), мы вырваться из петли и рассчитать высоту клавиатуры с помощью:

softkeyboard_height = mainScreenView.getHeight() - y; 

Код:

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

Отправка события указателя. Закончив в какой-то момент после получателя вернулся из обработки события, хотя он может не иметь полностью завершенного ответа , например, если он должен обновить свой экран, он все равно может быть в процесс выполнения этого.

+0

Является ли это общедоступным API? Я не могу найти документацию о 'INTERNAL_POINTER_META_STATE'. – rid

+0

@rid Извините. 'INTERNAL_POINTER_META_STATE' - целочисленная константа. Для цели вопроса использование любого целочисленного значения будет работать. Я редактировал код выше. Спасибо, что указали это. – Vikram

+0

Тем не менее, можно ли использовать это без возможности функциональности в любой будущей версии Android? Является ли это '1' гарантией всегда быть одинаковым? Документально ли он официально зарегистрирован Google? Можете ли вы полагаться на это, не опасаясь производить хрупкий код? – rid

1

Используйте OnGlobalLayoutListener, он отлично работает для меня.