How do I detect if software keyboard is visible on Android Device or not?
Solution 1
There is no direct way - see http://groups.google.com/group/android-platform/browse_thread/thread/1728f26f2334c060/5e4910f0d9eb898a where Dianne Hackborn from the Android team has replied. However, you can detect it indirectly by checking if the window size changed in #onMeasure. See How to check visibility of software keyboard in Android?.
Solution 2
This works for me. Maybe this is always the best way for all versions.
It would be effective to make a property of keyboard visibility and observe this changes delayed because the onGlobalLayout method calls many times. Also it is good to check the device rotation and windowSoftInputMode
is not adjustNothing
.
boolean isKeyboardShowing = false;
void onKeyboardVisibilityChanged(boolean opened) {
print("keyboard " + opened);
}
// ContentView is the root view of the layout of this activity/fragment
contentView.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Rect r = new Rect();
contentView.getWindowVisibleDisplayFrame(r);
int screenHeight = contentView.getRootView().getHeight();
// r.bottom is the position above soft keypad or device button.
// if keypad is shown, the r.bottom is smaller than that before.
int keypadHeight = screenHeight - r.bottom;
Log.d(TAG, "keypadHeight = " + keypadHeight);
if (keypadHeight > screenHeight * 0.15) { // 0.15 ratio is perhaps enough to determine keypad height.
// keyboard is opened
if (!isKeyboardShowing) {
isKeyboardShowing = true
onKeyboardVisibilityChanged(true)
}
}
else {
// keyboard is closed
if (isKeyboardShowing) {
isKeyboardShowing = false
onKeyboardVisibilityChanged(false)
}
}
}
});
Solution 3
try this:
InputMethodManager imm = (InputMethodManager) getActivity()
.getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm.isAcceptingText()) {
writeToLog("Software Keyboard was shown");
} else {
writeToLog("Software Keyboard was not shown");
}
Solution 4
I created a simple class that can be used for this: https://github.com/ravindu1024/android-keyboardlistener. Just copy it in to your project and use as follows:
KeyboardUtils.addKeyboardToggleListener(this, new KeyboardUtils.SoftKeyboardToggleListener()
{
@Override
public void onToggleSoftKeyboard(boolean isVisible)
{
Log.d("keyboard", "keyboard visible: "+isVisible);
}
});
Solution 5
Very Easy
1. Put id on your root view
rootView
is just a view pointing to my root view in this case a relative layout
:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/addresses_confirm_root_view"
android:background="@color/WHITE_CLR">
2. Initialize your root view in your Activity:
RelativeLayout rootView = (RelativeLayout) findViewById(R.id.addresses_confirm_root_view);
3. Detect if keyboard is opened or closed by using getViewTreeObserver()
rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
int heightDiff = rootView.getRootView().getHeight() - rootView.getHeight();
if (heightDiff > 100) { // Value should be less than keyboard's height
Log.e("MyActivity", "keyboard opened");
} else {
Log.e("MyActivity", "keyboard closed");
}
}
});
Related videos on Youtube
Comments
-
andreea about 2 years
Is there a way in Android to detect if the software (a.k.a. "soft") keyboard is visible on screen?
-
Heath Hunnicutt about 12 yearspossible duplicate of Android: how can i tell if the soft keyboard is showing or not?
-
Prof over 6 yearswhat can be a solution to this in certain cases (if a 3rd party keyboard is installed) is to check the global notifications as when a keyboard is open there is a system notification that says "change keyboard" - can be done with a NotificationListenerService
-
M.kazem Akhgary over 5 yearsalmost 8 years and still no solid solution, oh if they introduce one, its going to be for API > 30 anyway so never mind...
-
AbdelHady over 4 yearsPossible duplicate of Android: Detect softkeyboard open
-
-
Peter Ajtai about 12 yearsThis does not work for me. The keyboard shown branch triggers even in instance when the keyboard was never shown or was shown and then closed.
-
3c71 over 11 yearsDoesn't work for me. I only receive the Enter key in OnEditorAction.
-
Shivang Trivedi over 10 yearsit always return true.
-
Léon Pelletier about 10 yearsYeah, it always return true.
-
Gaurav Arora about 10 yearsWrong. This always returns true
-
Denys Kniazhev-Support Ukraine over 9 yearsThis will be called VERY often
-
Gopal Singh Sirvi almost 9 yearsThe question was related to find out either keyboard is showing or not
-
Boris Treukhov over 8 yearsFor me it sometimes returns false - when the keyboard is actually visible.
-
Vicky Chijwani over 8 yearsIt is pathetic that the Android framework is lacking, and worse, inconsistent in this regard. This ought to be super-simple.
-
iscariot over 8 yearsnot correctly working in some cases! Need something else
-
User3 over 8 yearsCan you improve this answer with a more concrete example, with all imports and a working example?
-
ToolmakerSteve over 8 yearsThis is only useful during development - not a solution for use in an app. (Users won't have adb running.)
-
Rarw about 8 yearsThis works. If you implement as singelton you can apply to all edittexts on focus change and have one global keyboard listener
-
Christopher Hackl about 8 years@depperm getActivity() is specific to Fragments, try YourActivityName.this instead. See also: stackoverflow.com/questions/14480129/…
-
toom over 7 yearsWhere in the code exaclty do I have to put this? I put this into an activity, however, it does not detect any keyboard appearance or disappearance.
-
ravindu1024 over 7 yearsWell, you can put it anywhere inside your activity. Just put it in the onCreate() method after the setContentView() call and you should be getting callbacks. Btw, what device are you trying it on?
-
Mahdi Astanei over 7 yearshow to call it and where?
-
anthonymonori over 7 yearsThis will only work for hardware keyboard, not he software one
-
Ganpat Kaliya over 7 yearsIt is not working for me it returns always true. if the keyboard is not open still return true.
-
Evan Langlois over 7 yearsIn what instances will this be different than @BrownsooHan answer? I'm looking for a way that an app that draws over other apps to get out of the way of the keyboard is showing.
-
PearsonArtPhoto over 7 yearsHis answer is fundamentally the same as mine, only I did mine many months before his, and he has more upvotes.
-
Faruk Toptas over 7 yearsHere is a working gist: gist.github.com/faruktoptas/e9778e1f718214938b00c2dcd2bed109
-
Justin about 7 yearsPut this in a utils class and pass in the activity - now useful across the whole app.
-
narancs almost 7 yearshey mate, could you please tell me where this magic 100 comes from? Why not 101 or 99? Thanks
-
ravindu1024 almost 7 years@MaulikDodia I checked and it works fine in fragments. Set it up like this: KeyboardUtils.addKeyboardToggleListener(getActivity(), this); and it should work. What device are you trying it on?
-
Maulik Dodia almost 7 yearsI'm trying on Moto-G3 device.@ravindu1024
-
Code-Apprentice almost 7 yearsAnd where is
contentView
declared? -
airowe almost 7 years@Code-Apprentice In the activity/fragment you're looking to respond to soft keyboard changes. ContentView is the root view of the layout of this activity/fragment.
-
Rushi M Thakker almost 7 yearsIt always returns false in my case when I have a keyboard open and I select an item in custom autocompleteview
-
Vlad over 6 years@Karoly i think this may be and
1
. No matter. Only this must be less than the real length of keyboard -
mr5 over 6 years@Karoly basically, he's comparing the window size with your activity's root view size. the appearance of the soft keyboard doesn't affect the size of the main window. so you can still lower the value of 100.
-
Vahe Gharibyan over 6 yearsNo any way to detect is keyboard open or close. It's very embarrassing measure height for detecting keyboard state. I tried to find keyboard state inside of WindowManager because keyboard must attache some window.
-
V.March almost 6 yearsWorked for me on Android 6 and 7.
-
Haresh Ramani almost 6 yearsthis is perfect for me
-
Zeeshan over 5 yearsThis logic is only for portrait mode. And onGlobalLayout() this method calls so many times, still looking for better solution.
-
Brownsoo Han over 5 years@ShanXeeshi Good point! It would be effective to make a property of keyboard visibility and observe this changes delayed because the onGlobalLayout method calls many times. Also check the device rotation.
-
Parth Patel over 5 yearsWorking in lower and higher devices
-
6rchid over 5 yearsThis obviously won't work since it's not a listener that listens to the soft keyboard's behavior.
-
user924 about 5 years@VickyChijwani believe me Android SDK is much better than iOS SDK. It's much easier to develop for Android. To detect internet connection in iOS you have to use such things like github.com/ashleymills/Reachability.swift (in Android you need a couple of lines without any third-party code)
-
user924 about 5 yearsThis bad because it always being called, even when I just scroll though items in RecyclerView
-
Brownsoo Han almost 5 years@vishalpatel If you use spited screen(fragment) with one activity, try to add listener to root of an activity.
-
Antroid almost 5 yearsnot really a hack, didnt work in a nested fragment case. Can't say on activities as i didnt try this on that yet.
-
Antroid almost 5 yearswhere would you remove Global layout listener. The number of times a global layout is called is unimagnable.
-
Brownsoo Han almost 5 years@antroid You need to create a property for checking keyboard visibility because GlobalLayoutListener called many many times. I updated codes.
-
Morten Holmgaard over 4 yearsThe magic number is dependent on your layout of topbar among other things. So it is relative to your app. I used 400 in one of mine.
-
Pratik Butani over 4 yearsThanks for this snippet, I have one question that is this code required to remove listener?
-
ravindu1024 over 4 years@PratikButaniAndroidDev There's a static function called
KeyboardUtils.removeAllKeyboardToggleListeners
. Call that when your Activity is destroyed. -
Pratik Butani over 4 yearsIs it required or not?
-
ravindu1024 over 4 yearsIt isn't required for it to work. However since the keyboard util class is holding a static reference to your activity to provide that callback you should unregister to avoid memory leaks.
-
9paradox over 4 yearsremember that onGlobalLayout is called every frame, so make sure you don't do heavy stuff in there.
-
Mandeep Singh over 4 yearsThe isKeyboardShown keep on calling itself when its not shown.
-
Edgar Khimich over 4 yearsthe fun onKeyboardVisibilityChanged() is actually can be removed Its better to put the code from there directly to the onGlobalLayoutListener The rest is work for me +1 Thanks
-
Syam Sundar K over 4 yearsthis will not be helpful if your layout involves a bottom sheet. Can't distinguish between a keyboard and bottom sheet.
-
Amar Singh about 4 yearsworking for me tested in 3 devices. motorola moto g5, micormax, nokia 6.1 plus
-
Foster almost 4 yearsWorks great. Thank you sm
-
kaustubhpatange almost 4 yearsAmazing use of reflections
-
Rafael almost 4 yearsThey did hide this method
-
dokam_scotland over 3 yearseasier solution ever for this situation ;)
-
Nurlan Nabiyev over 3 yearsСпасибо! Ты спас мое время =)
-
Tom Gilder over 3 yearsSee this video which also references this question! youtube.com/watch?v=acC7SR1EXsI 😁
-
user158 over 3 years@TomGilder just go ahead and make an edit to add the video to references.
-
Andrew over 3 yearsAnd what is "binding"
-
Emre Akcan over 3 years@Andrew it is root layout
-
Nishant Pardamwar over 3 yearsthis actually breaks when user do split screen apps.
-
Pointer Null over 3 yearsYes this works. Shame that we have to poll this, and some callback doesn't tell us when this changes.
-
Pravin Suthar about 3 yearsbut this is not working in other third-party apps
-
Saman Sattari about 3 yearsrequires api 20 at least
-
AndrazP almost 3 yearsI had to replace
WindowInsetsCompat.toWindowInsetsCompat(rootWindowInsets)
withViewCompat.getRootWindowInsets(this)
to get it working. Found it in Android video: youtu.be/acC7SR1EXsI?t=319 -
Aldan almost 3 yearsWorks perfectly if you're using
findViewById
, if using View Binding we got error(act.findViewById<View>(… ViewGroup).getChildAt(0) must not be null
any suggestion? -
Hitesh Bisht almost 3 yearsYou can write an extension function like this for API 21 and above. fun View.isKeyboardVisible(): Boolean { val insets = ViewCompat.getRootWindowInsets(this) return insets?.isVisible(WindowInsetsCompat.Type.ime()) ?: false }
-
Inside 4ndroid over 2 yearsyour code should have getWindow().getDecorView()
/** * Add global layout listener to observe system keyboard visibility */ private void initObserverForSystemKeyboardVisibility() { getWindow().getDecorView().getRootView().getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { //Add your own code here Log.d("TEST_CODE", "isSystemKeyboardVisible:" + isSystemKeyboardVisible()); } }); }
-
user924 over 2 yearsit has nothing to do with soft virtual keyboard
-
user924 over 2 yearsThead.sleep - what is that? Making Main thread sleep?
-
user924 over 2 yearsThead.sleep - what is that? Making Main thread sleep?
-
user924 over 2 yearsit returns 190, so it says that keyboard is always opened, this hardcoding is very bad
-
user924 over 2 yearsthis returns true for Android 23-29 even if keyboard is not opened, it only works ok for Android 30
-
Gert Arnold over 2 yearsYou need a very good reason to answer an old, abundantly answered question like this. New answers without any explanation how they complement other answers tend to get deleted in the review process.
-
Piotr Aleksander Chmielowski over 2 years@GertArnold If this -1 is from you, it would be more professional to at least explain what is wrong with the answer.
-
Gert Arnold over 2 yearsDidn't I do that? For all answers an explanation why it does what it does (and it's the best way) is always welcome, but new answers to old questions should also explain how they improve other answers. You don't want to how many people just drop answers without ever looking at existing answers and, thus, effectively only add noise. Either way, code-only answers are always deemed low quality answers and many of them get deleted by community moderation.
-
RufusInZen over 2 years
getInputMethodWindowVisibleHeight
method is blocked as part of using non-SDK API lists. You cannot use this reflection in production. See more info here: developer.android.com/guide/app-compatibility/… -
Ângelo Polotto over 2 yearsso far, the only solution that still works in 2022!
-
Muhammad Maqsood about 2 yearsThis workaround will work only when we have the below properties for activity in the Manifest file. android:windowSoftInputMode="adjustResize" or android:windowSoftInputMode="adjustPan" It will not work for below android:windowSoftInputMode="adjustNothing"