Is there a way in Android to detect if the software (a.k.a. \"soft\") keyboard is visible on screen?
So after a long time of playing around with AccessibilityServices, window insets, screen height detection, etc, I think I found a way to do this.
Disclaimer: it uses a hidden method in Android, meaning it might not be consistent. However, in my testing, it seems to work.
The method is InputMethodManager#getInputMethodWindowVisibleHeight(), and it's existed since Lollipop (5.0).
Calling that returns the height, in pixels, of the current keyboard. In theory, a keyboard shouldn't be 0 pixels tall, so I did a simple height check (in Kotlin):
val imm by lazy { context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager }
if (imm.inputMethodWindowVisibleHeight > 0) {
//keyboard is shown
else {
//keyboard is hidden
}
I use Android Hidden API to avoid reflection when I call hidden methods (I do that a lot for the apps I develop, which are mostly hacky/tuner apps), but this should be possible with reflection as well:
val imm by lazy { context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager }
val windowHeightMethod = InputMethodManager::class.java.getMethod("getInputMethodWindowVisibleHeight")
val height = windowHeightMethod.invoke(imm) as Int
//use the height val in your logic