sarò utilizzando il codice fornito al link che hai postato:
// Declare Variables
int softkeyboard_height = 0;
boolean calculated_keyboard_height;
Instrumentation instrumentation;
// Initialize instrumentation sometime before starting the thread
instrumentation = new Instrumentation();
mainScreenView
è la vostra vista di base, punto di vista di vostra attività. m
(ACTION_DOWN) e m1
(ACTION_UP) sono eventi di tocco che vengono inviati utilizzando Instrumentation#sendPointerSync(MotionEvent)
. La logica è che un MotionEvent inviato al punto in cui la tastiera viene visualizzata causerà la seguente SecurityException
:
java.lang.SecurityException: Iniezione a un'altra applicazione richiede l'autorizzazione INJECT_EVENTS
Quindi, iniziamo nella parte inferiore dello schermo e risalire (decrementando) su ogni iterazione del ciclo. Per un certo numero di iterazioni, otterremo una SecurityException (che cattureremo): ciò implicherebbe che MotionEvent si verifichi sulla tastiera. Nel momento in cui y
ottiene abbastanza piccolo (quando il suo appena sopra la tastiera), ci spezziamo fuori dal giro e calcoliamo l'altezza della tastiera:
softkeyboard_height = mainScreenView.getHeight() - y;
Codice:
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)
:
Invia un evento puntatore. Finito in qualche momento dopo che il destinatario è tornato dall'elaborazione dell'evento, anche se potrebbe non avere completamente finito di reagire dall'evento - ad esempio, se lo ha bisogno di aggiornare la sua visualizzazione come risultato, potrebbe essere ancora nel processo di farlo.
È un'API pubblica? Non riesco a trovare la documentazione su 'INTERNAL_POINTER_META_STATE'. – rid
@rid Scusaci. 'INTERNAL_POINTER_META_STATE' è una costante intera. Per lo scopo della domanda, l'utilizzo di qualsiasi valore intero potrebbe funzionare. Ho modificato il codice sopra. Grazie per segnalarlo. – Vikram
Ancora, è sicuro usare questo senza che la funzionalità abbia la possibilità di sparire in qualsiasi versione futura di Android? È garantito che '1' sia sempre lo stesso? È documentato ovunque da Google ufficialmente? Puoi fare affidamento su questo senza paura di produrre codice fragile? – rid