Я буду использовать код, предоставленный в ссылке, которую вы публикуемая:
// 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)
:
Отправка события указателя. Закончив в какой-то момент после получателя вернулся из обработки события, хотя он может не иметь полностью завершенного ответа , например, если он должен обновить свой экран, он все равно может быть в процесс выполнения этого.
Является ли это общедоступным API? Я не могу найти документацию о 'INTERNAL_POINTER_META_STATE'. – rid
@rid Извините. 'INTERNAL_POINTER_META_STATE' - целочисленная константа. Для цели вопроса использование любого целочисленного значения будет работать. Я редактировал код выше. Спасибо, что указали это. – Vikram
Тем не менее, можно ли использовать это без возможности функциональности в любой будущей версии Android? Является ли это '1' гарантией всегда быть одинаковым? Документально ли он официально зарегистрирован Google? Можете ли вы полагаться на это, не опасаясь производить хрупкий код? – rid