How To Check If The Software Keyboard Is Shown In AndroidBy Roger Keays, 21 February 2012 |
How To Check If The Software Keyboard Is Shown In AndroidHere is a method to detect if the soft keyboard is visible on the screen in Android. All the other methods I have seen test the height of screen elements to guess whether it is displayed. This doesn't work for keyboards like WifiKeyboard which is an invisible keyboard.
This method uses the callback result of InputMethodManager.showSoftInput() to determine if the keyboard status changed. This is suitable for me because I need to call showSoftInput() anyway if the keyboard is not shown. The result from the operation needs to be polled because it is asynchronous. This example only polls 500 milliseconds and assumes that anything longer than that is caused by the keyboard being loaded and rendered.
Here is how the code is used:
// try to show the keyboard and capture the result
InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
IMMResult result = new IMMResult();
imm.showSoftInput(editText, 0, result);
// if keyboard doesn't change, handle the keypress
int res = result.getResult();
if (res == InputMethodManager.RESULT_UNCHANGED_SHOWN ||
res == InputMethodManager.RESULT_UNCHANGED_HIDDEN) {
showTags();
}
How To Check If The Software Keyboard Is Shown In Android
The IMMResult class is the key element. It looks like this:
/**
* To capture the result of IMM hide/show soft keyboard
*/
private class IMMResult extends ResultReceiver {
public int result = -1;
public IMMResult() {
super(null);
}
@Override
public void onReceiveResult(int r, Bundle data) {
result = r;
}
// poll result value for up to 500 milliseconds
public int getResult() {
try {
int sleep = 0;
while (result == -1 && sleep < 500) {
Thread.sleep(100);
sleep += 100;
}
} catch (InterruptedException e) {
Log.e("IMMResult", e.getMessage());
}
return result;
}
}
The useful result values are:
-
InputMethodManager.RESULT_UNCHANGED_SHOWN
-
InputMethodManager.RESULT_UNCHANGED_HIDDEN
-
InputMethodManager.RESULT_SHOWN
- InputMethodManager.RESULT_HIDDEN
See the InputMethodManager documentation for details.
Hope this helps you!
About Roger Keays
|
Roger Keays is an artist, an engineer, and a student of life. He has no fixed address and has left footprints on 40-something different countries around the world. Roger is addicted to surfing. His other interests are music, psychology, languages, the proper use of semicolons, and finding good food.
|
I don't think that busy waiting on the result is a good idea.
I tried alot of different approches as well, and yours worked most reliably.
I made some simplifications and posted it on SO:
http://stackoverflow.com/questions/4745988/how-do-i-detect-if-software-keyboard-is-visible-on-android-device/31090451#31090451
I have the same problem as Glen, my onReceiveResult is apparently not called.
As an aside, I didn't see the need for the polling as opposed to simply overriding the onReceiveResult callback, except that the polling provides the ability to get a response even if the callback isn't called. Although in this case, it provides no real information?
Hi Roger, thank you for sharing this with us. But for some reason the result code is always -1 for me, indicating that onReceiveResult is never called.
Do you have any suggestions at all?
Thank you again.
Hi Priyanka, That's an odd requirement. I'm not sure it is possible since capturing keyboard input has security implications. Let me know if you manage to figure it out...
Hey Roger,
I was wondering if you know how to detect key press from on screen Keyboard in android. I want to catch Ctrl+shift+i+k and show a dialog. But i am able to do that only when i am using physical keyboard and not with the on screen keyboard. Hope you can help.
Thanks,
Priyanka.
I don't need to show the keyboard manually. I just want to detect when it changes its state (shown/hidden) with appropriate callback function. Does it possible?
- Put the IMMResult private class in your Activity (or in a separate file if you need to reuse it).
- Put the first code block wherever you need conditional logic based on the state of the keyboard. This code block first shows the keyboard then checks the IMMResult to find out if it was hidden beforehand or not. You could change it to first hide the keyboard then query the result if that works better for you.
It's quite a mess really, but it should give you the information you need.
Missing API features FTW.
Just don't understand how to integrate this with Activity. Can you comment this more?