I'm trying to detect the virtual keyboard height in Android.
I found a similar topic: Get the height of virtual keyboard in Android
It seems the author found a way to detect the height:
I found a way to get it. After I request to open virtual keyboard, I send pointer event that I generate. their y coordinate starts from height of device and decreases.
I don't understand how to do that.
The element can only be the target of a pointer event when the visibility property is set to visible and e.g. when a mouse cursor is over the interior (i.e., 'fill') of the element and the fill property is set to a value other than none , or when a mouse cursor is over the perimeter (i.e., 'stroke') of the element and ...
Use the getPointerId(int) method to obtain the pointer id of a pointer to track it across all subsequent motion events in a gesture. Then for successive motion events, use the findPointerIndex(int) method to obtain the pointer index for a given pointer id in that motion event.
Pointer events are DOM events that are fired for a pointing device. They are designed to create a single DOM event model to handle pointing input devices such as a mouse, pen/stylus or touch (such as one or more fingers). The pointer is a hardware-agnostic device that can target a specific set of screen coordinates.
I'll be using the code provided at the link that you posted:
// Declare Variables
int softkeyboard_height = 0;
boolean calculated_keyboard_height;
Instrumentation instrumentation;
// Initialize instrumentation sometime before starting the thread
instrumentation = new Instrumentation();
mainScreenView
is your base view, your activity's view. m
(ACTION_DOWN) and m1
(ACTION_UP) are touch events that are dispatched using Instrumentation#sendPointerSync(MotionEvent)
. The logic is that a MotionEvent dispatched to where the keyboard is being displayed will cause the following SecurityException
:
java.lang.SecurityException: Injecting to another application requires INJECT_EVENTS permission
So, we start at the bottom of the screen and make our way up (by decrementing y
) on every iteration of the loop. For certain number of iterations, we will get a SecurityException (which we'll catch): this would imply that the MotionEvent is happening over the keyboard. The moment y
gets small enough (when its just above the keyboard), we'll break out of the loop and calculate the keyboard's height using:
softkeyboard_height = mainScreenView.getHeight() - y;
Code:
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)
:
Dispatch a pointer event. Finished at some point after the recipient has returned from its event processing, though it may not have completely finished reacting from the event -- for example, if it needs to update its display as a result, it may still be in the process of doing that.
Use OnGlobalLayoutListener, it works perfectly for me.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With