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.
Czy to jest publiczny interfejs API? Nie mogę znaleźć dokumentacji dotyczącej "INTERNAL_POINTER_META_STATE". – rid
@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
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