There are plenty of answers explaining how to close Android's soft keyboard (such as this one), but they all assume that the keyboard was opened from within your own app, or that you already have views which can obtain focus, thereby trumping the needs of the previous app. Within Android's InputMethodManager
class, requests to close a keyboard opened by another app are rejected, and the call to hideSoftInputFromWindow()
returns false.
A developer on my team created an extension method on Activity
that calls a block of code whenever keyboard state changes. Because Android doesn't fire keyboard show/hide events on its own (which is ridiculous), it's common practice to detect a reduction in the height of the Activity
root layout, and assume this means the keyboard was opened. (Note: this only works with windowSoftInputMode="adjustResize"
.) This extension method, which is meant to be called in onCreate()
, notes the height of the root layout at the time it's called, and watches for subsequent changes in height. If the height of the layout has become smaller, it's assumed that the keyboard has been shown. If it then gets bigger, it's assumed the keyboard was hidden. While this sort of non-deterministic hack is unfortunate, it can be useful, as long as you aren't depending on 100% accuracy.
Unfortunately, it doesn't work in this scenario:
- User start in another app, with the keyboard open
- User taps a notification from my app
- My app opens (cold start), with the keyboard still open from the other app
- When the extension method is called from onCreate(), the height of my Activity's root layout already reflects the fact that the keyboard is open, which breaks the concept of watching for it to get shorter when the keyboard is open
While there are potentially some ways to refine the logic to make it more robust, what I really want to do is reliably close the "foreign" keyboard that's throwing off my baseline measurement of the app's height. But I've tried setting windowSoftInputMode="stateHidden"
in my AndroidManifest.xml
file for the Activity
in question, and I've tried calling InputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0)
. Neither approach works; if the keyboard was opened by another app, and I don't yet have a view that has focus, InputMethodManager
rejects my attempts to close the keyboard, presumably as a way to prevent my gaining control over the visibility of a keyboard owned by another app.
Is there a way to immediately close a lingering keyboard from another app when starting your own Activity
, such that the keyboard is gone by the time your first layout occurs? In my opinion, the fact that stateHidden
doesn't do this for you is a bug.