How to check visibility of software keyboard in Android?
Asked Answered
C

45

559

I need to do a very simple thing - find out if the software keyboard is shown. Is this possible in Android?

Collocation answered 27/1, 2010 at 20:39 Comment(11)
Although Reuben Scratton's answer is good it seems broken on a tablet. I replaced the check diff>128 with diff>screenHeight/3.Knuth
Reuben Scratton's answer was good but I required KaChi's adjustment to actually use it.Kronick
Instead of just checking height difference, we can do View v = this.getCurrentFocus();if (diff>100 && v != null){ // Its keyboard } else { //Keyboard hidden }Bradybradycardia
You can try this approach, worked well for me. #4746488Shallop
still raging about this in 2018Attu
I found a way to do this: #4746488 (cc @FloWe)Rident
Why Google don't make a standard builtin method works for all keyboard app ?Recurrence
For those who are searching for an answer, here is a more neat solution: https://mcmap.net/q/36355/-detecting-when-user-has-dismissed-the-soft-keyboardSleep
It still brothers me, that this is not a system functions...Trident
It's absolutely nuts that this API is still missing 10 years later. Very glad I moved away from Android.Disciple
you can find answer there #25217249Ascot
D
699

NEW ANSWER added Jan 25th 2012

Since writing the below answer, someone clued me in to the existence of ViewTreeObserver and friends, APIs which have been lurking in the SDK since version 1.

Rather than requiring a custom Layout type, a much simpler solution is to give your activity's root view a known ID, say @+id/activityRoot, hook a GlobalLayoutListener into the ViewTreeObserver, and from there calculate the size diff between your activity's view root and the window size:

final View activityRootView = findViewById(R.id.activityRoot);
activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        int heightDiff = activityRootView.getRootView().getHeight() - activityRootView.getHeight();
        if (heightDiff > dpToPx(this, 200)) { // if more than 200 dp, it's probably a keyboard...
            // ... do something here
        }
     }
});

Using a utility such as:

public static float dpToPx(Context context, float valueInDp) {
    DisplayMetrics metrics = context.getResources().getDisplayMetrics();
    return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, valueInDp, metrics);
}

Easy!

Note: Your application must set this flag in Android Manifest android:windowSoftInputMode="adjustResize" otherwise above solution will not work.

ORIGINAL ANSWER

Yes it's possible, but it's far harder than it ought to be.

If I need to care about when the keyboard appears and disappears (which is quite often) then what I do is customize my top-level layout class into one which overrides onMeasure(). The basic logic is that if the layout finds itself filling significantly less than the total area of the window, then a soft keyboard is probably showing.

import android.app.Activity;
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.widget.LinearLayout;

/*
 * LinearLayoutThatDetectsSoftKeyboard - a variant of LinearLayout that can detect when 
 * the soft keyboard is shown and hidden (something Android can't tell you, weirdly). 
 */

public class LinearLayoutThatDetectsSoftKeyboard extends LinearLayout {

    public LinearLayoutThatDetectsSoftKeyboard(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public interface Listener {
        public void onSoftKeyboardShown(boolean isShowing);
    }
    private Listener listener;
    public void setListener(Listener listener) {
        this.listener = listener;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int height = MeasureSpec.getSize(heightMeasureSpec);
        Activity activity = (Activity)getContext();
        Rect rect = new Rect();
        activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
        int statusBarHeight = rect.top;
        int screenHeight = activity.getWindowManager().getDefaultDisplay().getHeight();
        int diff = (screenHeight - statusBarHeight) - height;
        if (listener != null) {
            listener.onSoftKeyboardShown(diff>128); // assume all soft keyboards are at least 128 pixels high
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);       
    }

    }

Then in your Activity class...

public class MyActivity extends Activity implements LinearLayoutThatDetectsSoftKeyboard.Listener {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        LinearLayoutThatDetectsSoftKeyboard mainLayout = (LinearLayoutThatDetectsSoftKeyboard)findViewById(R.id.main);
        mainLayout.setListener(this);
        ...
    }


    @Override
    public void onSoftKeyboardShown(boolean isShowing) {
        // do whatever you need to do here
    }

    ...
}
Disciple answered 19/1, 2011 at 15:42 Comment(57)
This wasn't working for me until I realized that you must set the following attribute on your activity: android:windowSoftInputMode="adjustResize"Pegg
I cant do the cast to LinearLayoutThatDetectsSoftKeyboard from my LinearLayoutAfferent
+1, but what a pain... (I'm using the check in a functional test)Management
This might be a stupid question, but how do I specify that my XML layout should be using this custom LinearLayout class??Lindseylindsley
Seems to be doing the trick. Also, if you don't know the root view's ID, here's how you can get the view: ((ViewGroup) findViewById(android.R.id.content)).getChildAt(0)Askew
Thanks for the update Reuben. This was indeed very useful. I will be posting an example project for this that will link to your answer and your profile.Pasteurizer
Thanks Reuben, i did try your way and it worked for me too but it does not work when i remove the title bar... any suggestion plsGoldthread
Hi, Your answer to this post helped me greatly but however, since listener gets called everytime(I don't know why.....) I can't do anything with the layout. For example, I inserted a Toast when Keyboard is showing then the Toast keeps on popping up which means listener is getting called all the time.... Is there anyway to stop this? Is this because I implemented listener on the activity not like the way you created it?Sorrento
Hi, if your original answer is based on this answer from 2010 { #3410237 } then a credit is due. If not, then great minds think alike :)Highsounding
increased if (heightDiff > 200) to 200... 100 didnt work for me tested it on QVGA (wildfire etc) devices, works as well .. :)Carmelcarmela
If you try this using the actual root view (android.R.id.content) you will be able to more confidently say that the System rather than your application is the entity changing it's height. Would be much safer for the Android team to give us a break and let us know at least basic things about the SoftKeyboard input.Isodimorphism
Setting android:windowSoftInputMode="adjustResize" hides the EditText where the user is writing in some situations, so I couldn't use this approach.Sukiyaki
@Sorrento You're right the listener is called every time. Check out the answer here to solve it: #7300997Duodenary
Make sure you add the listener back to the view tree each time the view is attached to the displayed view hierarchy. The listener is removed each time it is detached.Tashinatashkent
Beware that heightDiff will always include the height of the action bar. In the new answer that has been ignored by testing if that height is greater than some constant, but 100 pixels is not sufficient for xxhdpi devices such as the Nexus 4. Consider converting that value to DPs if you really want to use this hacky work-around.Lutherlutheran
Pardon the typo. The Nexus 4 is xhdpi, not xxhdpi. (Presently there are no xxhdpi devices; that qualifier is currently only used for the Nexus 10's launcher.)Lutherlutheran
At the time this answer was written there was no such thing as an ActionBar.Disciple
The Droid DNA should be xxhdpiBloomery
In reply to Reuben Scratton's new answer. When using a viewpager you should use: activityRootView = mContext.mViewPager.getRootView();Desperado
@Reuben I have a dialog with EditText need to do the same trick, but when I hide the soft keyboard with the key on it, can't get the global layout event(because the dialog size is not change? ), how could I detect this keyboard hide event? I know the position of the dialog on the screen will change, is it possible to catch that?Glorianna
Note that this has nothing really to do with the soft keyboard. Hiding and showing of the system bar equivalent on a Kindle Fire will cause changes in heights as well. I would not be surprised if this caused problems on other vendor-specific scenarios, such as Samsung's multi-window mode. It also makes gross assumptions regarding the size of soft keyboards, which can and do vary (and cannot readily be determined ahead of time by the app). Hence, this reports about UI changes that may or may not be caused by the soft keyboard.Hyperextension
All true of course. I imagine those wanting this hack don't care about their UI being constrained by the keyboard particularly, just that their UI is being constrained at all. I wonder if the act of showing or hiding the keyboard shouldn't ideally trigger a resource config change, i.e. loading a layout suited to the reduced window size. Perhaps it'd make sense for windowSoftInputMode to have an option for that.Disciple
This works, but it seems that the listener is only called when the activity is still running. Is there a way to do it outside the activity in which this is implemented in? If I were to minimize my main app, and perhaps bring up the keyboard through a google search?Symphonious
You could manually invoke the listener from Activity.onResume() ?Disciple
I mean the listener is only called on your application's activity; doesn't seem that the listener is invoked when another activity brings up a keyboard.Symphonious
It doesn't work for android:windowSoftInputMode="adjustPan". I wanted that my screen shouldn't get shrinked after soft keyboard appears. Can you please tell any fix so that it works even for adjustPanProject
I use a similar set up - but your setup doesn't allow for Chinese and Japenese keyboards who's "suggestion" rulers (which are required) make the screen area grow and shrink by more than 100 (Nexus 10). Instead, where possible, try and use ScreenHeight / 4 as the "fudge" value, as in all instances we've found a keyboard takes up at least 1/4 of the screen and any "suggestion bars" take up less than 1/4. (Remember to add an onOrientationChange method to reset the 1/4 value).Isodimorphism
I suggest you use dp and not pixels. I personally use >100dp.Nationwide
But it's not working with me. i have 4 edittext on my activity. if i click on any edittext then it scrolling up but i want to scroll up screen when i click on any specific edittextSelfconsequence
@ReubenScratton can you take a look at it. #20885586Selfconsequence
Notice: not working with WindowManager.LayoutParams.FLAG_FULLSCREEN and with a full screen theme.Pyrrhotite
@PaulLammertsma And even with DP, 100 is too small — 200 may be more safe choice.Historiography
Use (height > 200) for keyboard open even and (height < 200) for keyboard close event :)Astrakhan
I think solution needs some kind of mechanism to check whether keyboard is opening or closing because of layout will change in both cases!Entresol
@PaulLammertsma you can get the height of the action bar in pixels instead: #7166330 So you can remove the action bar height from the height diff.Lamphere
@Reuben Scratton hi sir. my root linearLayout name is main and after using your code i get this error: android.widget.LinearLayout cannot be cast to com.sample.Class.LinearLayoutThatDetectsSoftKeyboardDisorganization
FYI: I have a Scroll View, and I used android:windowSoftInputMode="stateHidden|adjustPan" which I set in <application > part of the manifest file, works fine. It does re-size my scrollview so I can scroll to the bottom while the keyboard is shown, perhaps a quick tip: scrollView.smoothScrollTo(0,70); to make it scroll down (or to specific Y)Fascinator
How about detecting hide soft keyboard event? You can't be sure by checking whether there is no height difference because there might be something else triggering GlobalLayoutListener which i am not fully in knowledge of.Pamphleteer
How about android:windowSoftInputMode="adjustNothing" ? Thanks. I need to set android:windowSoftInputMode to adjustNothing .Utilitarian
Please do use 215 and above for XXHDPI (Similar to HTC One) .Gewgaw
This does not work if you enabled the KitKat immersive mode.Stepheniestephens
Don't forget to remove the listener when done with it: activityRootView.getViewTreeObserver().removeOnGlobalLayoutListener(this);Bowl
This solution was too memory consuming. As soon as I implemented this, Kernel usage increased from 0 to 2% and User usage raised by 4%.Anility
I logged it. And onSoftKeyboardShown calling 3 times when keyboard is opened and 2 time when keyboard is closed. Can you explain why it calls many times?Semeiology
for hi resolution devices use heightDiff > root.getRootView().getHeight() / 4Amand
Edited the "new answer" to use a DP value, so that it has a chance of working on newer devices too (as commented earlier by Paul Lammertsma and Sarge Borsch).Isopod
actually the (heightdifference > screenHeight / 3) worked for me. i.e if the height difference is greater than that, I am taking keyboard as shown.Leodora
It doesn't cover all devices. This answer is not generic.Becka
@Reuben Scratton what is COMPLEX_UNIT_DIP? i meant what is the value of that object?Tetrafluoroethylene
@SagarChavada TypedValue.COMPLEX_UNIT_DIPIts
@VAV, possibly this will work for a full screen: https://mcmap.net/q/36361/-android-how-to-adjust-layout-in-full-screen-mode-when-softkeyboard-is-visible (I mean adjusting a size of layout).Suavity
Just wondering, shouldn't you remove the global layout listener at some point to avoid memory leaks? (onDestroy for example)Jennet
Why not android.R.id.content in findViewByIdEdwyna
Is there still no simple way of finding this out? :CMcclurg
Thanks for the answer. It's 2019 and I created a more neat solution: https://mcmap.net/q/36355/-detecting-when-user-has-dismissed-the-soft-keyboardSleep
This solution is not working for coordinator layout rootRye
Hi Reuben how are you? i have a question : why else{} that you did not write it has multiple action?(when keyboard comes up if{} run just once but else{} run multi time)Anastassia
U
311

So hopefully this helps someone out.

The new answer that Reuben Scratton gave is great and really efficient, but it really only works if you set your windowSoftInputMode to adjustResize. If you set it to adjustPan, it's still not possible to detect whether or not the keyboard is visible using his code snippet. To work around this, I made this tiny modification to the code above.

final View activityRootView = findViewById(R.id.activityRoot);
activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
    Rect r = new Rect();
    //r will be populated with the coordinates of your view that area still visible.
    activityRootView.getWindowVisibleDisplayFrame(r);
   
    int heightDiff = activityRootView.getRootView().getHeight() - r.height();
    if (heightDiff > 0.25*activityRootView.getRootView().getHeight()) { // if more than 25% of the screen, its probably a keyboard...
        ... do something here
    }
 }
}); 
Uprise answered 2/2, 2012 at 6:45 Comment(22)
This is the one that worked for me. I was attempting to detect keyboard state from a custom TwoDScrollerView similar to https://mcmap.net/q/36362/-scrollview-vertical-and-horizontal-in-android although with zooming too. The child was not a simple ImageView but a custom layout (extends RelativeLayout) but was unable to detect the keyboard using the recommended solution despite setting android:windowSoftInputMode="adjustResize". Thanks!Fibrillation
Thank you thank you thank you! adjustResize just isn't viable for my app and your solution worked perfectly.Circumscissile
Works with ActionBar and ActionBarSherlock. Thanks a lot! By the way, there is a method r.height() :)Capitalism
I'll attach a bounty here within 23 hours to mark this answer somehow.Capitalism
I was using adjustPan due to scrolling views on my tabhost so this was a big help. I was spawning the Android mail client in one tabhost and hitting "Discard" would leave the keyboard up. Since none of my views need a keyboard (no EditText widgets), I just call imm.toggleSoftInput (InputMethodManager.SHOW_FORCED,0) directly in onGlobalLayou() when heightDiff > 100.Casing
It doesn't work for android:windowSoftInputMode="adjustPan". I wanted that my screen shouldn't get shrinked after soft keyboard appears. Can you please tell any fix so that it works even for adjustPanProject
Works very nice... though I've just learned that the condition should have an extra else, if (heightDiff == 0) {\*Too many times called and it has nothing to do with the keyboard...*\}, at least on my S4 it does...Intransitive
Worked for me nicely on S4, Android OS v4.2.2.Tews
I use a similar set up - but your setup doesn't allow for Chinese and Japenese keyboards who's "suggestion" rulers (which are required) make the screen area grow and shrink by more than 100 (Nexus 10). Instead, where possible, try and use ScreenHeight / 4 as the "fudge" value, as in all instances we've found a keyboard takes up at least 1/4 of the screen and any "suggestion bars" take up less than 1/4. (Remember to add an onOrientationChange method to reset the 1/4 value).Isodimorphism
Thanks kachi..u r genious works for me. After trying n trying i got solution.Woodford
This solution worked the most consistently for me on several devices and emulators running v3.2 - v4.4.2. I first tried Reuben Scratton's updated answer on devices and emulators listed above, but there were instances where the height difference didn't update the first time the keyboard displayed, but on subsequent tries, it did. Note that I didn't need to set windowSoftInputMode (in manifest or in Java). I just placed the code in my main activity's onCreate. Just to be safe, I also used a higher height difference value in my test. Thank you, Kachi.Mcalpine
Thank you works perfectly, and it's more efficient than @Reuben's method. I've added an else to the condition to catch when the keyboard isn't show :) Thanks again ;)Monumentalize
for both open-close states: if (heightDiff > 100 && !keyBoardOpen) { // if more than 100 pixels, its probably a keyboard... keyBoardOpen = true; onKeyBoardOpen(); } else if (heightDiff < 100 && keyBoardOpen) { keyBoardOpen = false; onKeyBoardClosed(); }Vulgarity
Thank you! I used this on my messages for the list to auto scroll to bottom when the keyboard pops up!Inattention
heightDiff > root.getRootView().getHeight() / 4 is good value to work with high resolution device. 100px is to short. in Nexus 5 with 1080x1920 res, 1920 - (996-75) >? 100 = 999 1920 - (1776-75) >? 100 = 219 // keyboard is up in galaxy s2 with 480x800 res, 800 - (800-38) >? 100 = 38 800 - (410-38) >? 100 = 428 // keyboard is up so, magic number 100px is not good enough.Connaught
How about android:windowSoftInputMode="adjustNothing" ? Thanks. I need to set android:windowSoftInputMode to adjustNothing .Utilitarian
Flask_KR's proposal is good - I used (diff > 200) and it worked on Nexus 4, but not on Nexus 5.Joule
Agree with @Flask_KR, on my LG G4 the heightDiff is 168 when the keyboard is not shown, so 100px does not apply to all phones, I am currently using heightDiff > root.getRootView().getHeight() / 4 too. The solution works perfectly though!Termination
This is broken on newer phone such as the Pixel 3 XLAutoionization
@Isodimorphism I use this way to detect the keyboard, but onGlobalLayout not called sometimes, it is not reliable. Have you encounter this issue?Hajj
For split view this solution doesn't work fine. For normal full screen, it serves the purpose.Gal
Hi kachi how are you? i have a question : why else{} that you did not write it has multiple action?(when keyboard comes up if{} run just once but else{} run multi time)Anastassia
I
57

It has been forever in terms of computer but this question is still unbelievably relevant!

So I've taken the above answers and have combined and refined them a bit...

public interface OnKeyboardVisibilityListener {


    void onVisibilityChanged(boolean visible);
}

public final void setKeyboardListener(final OnKeyboardVisibilityListener listener) {
    final View activityRootView = ((ViewGroup) getActivity().findViewById(android.R.id.content)).getChildAt(0);

    activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

        private boolean wasOpened;

        private final int DefaultKeyboardDP = 100;

        // From @nathanielwolf answer...  Lollipop includes button bar in the root. Add height of button bar (48dp) to maxDiff
        private final int EstimatedKeyboardDP = DefaultKeyboardDP + (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? 48 : 0);

        private final Rect r = new Rect();

        @Override
        public void onGlobalLayout() {
            // Convert the dp to pixels.
            int estimatedKeyboardHeight = (int) TypedValue
                    .applyDimension(TypedValue.COMPLEX_UNIT_DIP, EstimatedKeyboardDP, activityRootView.getResources().getDisplayMetrics());

            // Conclude whether the keyboard is shown or not.
            activityRootView.getWindowVisibleDisplayFrame(r);
            int heightDiff = activityRootView.getRootView().getHeight() - (r.bottom - r.top);
            boolean isShown = heightDiff >= estimatedKeyboardHeight;

            if (isShown == wasOpened) {
                Log.d("Keyboard state", "Ignoring global layout change...");
                return;
            }

            wasOpened = isShown;
            listener.onVisibilityChanged(isShown);
        }
    });
}

Works for me :)

NOTE: If you notice that the DefaultKeyboardDP does not fit your device play with the value and post a comment for everyone to know what should be the value... eventually we will get the correct value to fit all devices!

For more details, check out the implementation on Cyborg

Intransitive answered 24/9, 2013 at 21:58 Comment(15)
+1 Thank you so much!! I was trying the other answers, but they don't work. Then I found yours and it works like a charm. Awesome code! :DPoser
this works only if you add : android:windowSoftInputMode="stateHidden|adjustPan" or android:windowSoftInputMode="stateHidden|adjustResize" Thank you !!!!Hydantoin
Are you sure? If memory servers, I got the events properly also when the android:windowSoftInputMode had its default value... the only thing that didn't work out is the behavior of the screen, so I manually shrank it...Intransitive
If all you want to know is if the keyboard has been opened... use this!Newel
a small correction : private final int EstimatedKeyboardDP = DefaultKeyboardDP + (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? 48 : 0);Mythopoeic
I recommend to handle default keyboard heigh this way : final int defKeyboardDp = getResources().getDimensionPixelSize(R.dimen.default_keyboard_dp); whete default_keyboard_dp have value 100dpRennin
Works perfect on a Nexus 5, Android 5.1.1 with a webview + keyboard.Abercrombie
The only solution which works. Tested on APIs 16, 21, 22, 23.Ahmad
This solution work perfectly even on device rotation. If you are using Cordova webviews then you should use View activityRootView = activity.findViewById(android.R.id.content);Emirate
Thanks! I made a similar solution in a fragment, then opened another fragment. In this case I got an exception that activityRootView == null. If probably you will have this exception, check if (activityRootView != null) ... inside public void onGlobalLayout().Suavity
@Suavity Perhaps you called the listener too early, before the fragment was attached to the activity.. (BTW I do not use fragments they are badly architected, and hold the potential to numerous bugs)Intransitive
@TacB0sS, I agree with you. It is interesting that some programmers can use only activities without fragments.Suavity
@CoolMind.. funny you say that.. I also barely use Activities as well ;) github.com/nu-art/cyborg-coreIntransitive
@Lena Bru I didn't use your "inputmode", but it also works~Collator
Excellent!! No matter the "windowSoftInputMode" is set to"adjustPan" / "adjustResize" / "adjustPan|stateHidden" / "adjustResize|stateHidden", or even without this option, it always works! Tested on XiaoMi 8.Collator
M
51

Sorry for the late answer, but I had created a little helper class to handle open/close events with notifying listeners and other useful things, may be someone would find it helpful:

import android.graphics.Rect;
import android.view.View;
import android.view.ViewTreeObserver;

import java.util.LinkedList;
import java.util.List;

public class SoftKeyboardStateWatcher implements ViewTreeObserver.OnGlobalLayoutListener {

    public interface SoftKeyboardStateListener {
        void onSoftKeyboardOpened(int keyboardHeightInPx);
        void onSoftKeyboardClosed();
    }

    private final List<SoftKeyboardStateListener> listeners = new LinkedList<SoftKeyboardStateListener>();
    private final View activityRootView;
    private int        lastSoftKeyboardHeightInPx;
    private boolean    isSoftKeyboardOpened;

    public SoftKeyboardStateWatcher(View activityRootView) {
        this(activityRootView, false);
    }

    public SoftKeyboardStateWatcher(View activityRootView, boolean isSoftKeyboardOpened) {
        this.activityRootView     = activityRootView;
        this.isSoftKeyboardOpened = isSoftKeyboardOpened;
        activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(this);
    }

    @Override
    public void onGlobalLayout() {
        final Rect r = new Rect();
        //r will be populated with the coordinates of your view that area still visible.
        activityRootView.getWindowVisibleDisplayFrame(r);

        final int heightDiff = activityRootView.getRootView().getHeight() - (r.bottom - r.top);
        if (!isSoftKeyboardOpened && heightDiff > 100) { // if more than 100 pixels, its probably a keyboard...
            isSoftKeyboardOpened = true;
            notifyOnSoftKeyboardOpened(heightDiff);
        } else if (isSoftKeyboardOpened && heightDiff < 100) {
            isSoftKeyboardOpened = false;
            notifyOnSoftKeyboardClosed();
        }
    }

    public void setIsSoftKeyboardOpened(boolean isSoftKeyboardOpened) {
        this.isSoftKeyboardOpened = isSoftKeyboardOpened;
    }

    public boolean isSoftKeyboardOpened() {
        return isSoftKeyboardOpened;
    }

    /**
     * Default value is zero {@code 0}.
     *
     * @return last saved keyboard height in px
     */
    public int getLastSoftKeyboardHeightInPx() {
        return lastSoftKeyboardHeightInPx;
    }

    public void addSoftKeyboardStateListener(SoftKeyboardStateListener listener) {
        listeners.add(listener);
    }

    public void removeSoftKeyboardStateListener(SoftKeyboardStateListener listener) {
        listeners.remove(listener);
    }

    private void notifyOnSoftKeyboardOpened(int keyboardHeightInPx) {
        this.lastSoftKeyboardHeightInPx = keyboardHeightInPx;

        for (SoftKeyboardStateListener listener : listeners) {
            if (listener != null) {
                listener.onSoftKeyboardOpened(keyboardHeightInPx);
            }
        }
    }

    private void notifyOnSoftKeyboardClosed() {
        for (SoftKeyboardStateListener listener : listeners) {
            if (listener != null) {
                listener.onSoftKeyboardClosed();
            }
        }
    }
}

Usage example:

final SoftKeyboardStateWatcher softKeyboardStateWatcher 
    = new SoftKeyboardStateWatcher(findViewById(R.id.activity_main_layout);

// Add listener
softKeyboardStateWatcher.addSoftKeyboardStateListener(...);
// then just handle callbacks
Mach answered 14/10, 2013 at 5:53 Comment(11)
The class isnt little but the implementation surely is :). Thanks I will try this :)Broadcloth
Ping me if you got problems with it :) I successfully used it in 2 projectsMach
After trying many examples above and running into minor issues, this one was the one that worked best for me across many different devices (including xxhdpi). Plus it's in its own nice reusable class. I converted it over to be used in mono droid.Toots
Some keyboards, some of the time, have an extra row of custom keys on top (for instance, predicted words). These are apparently not part of the keyboard itself, since using the getLastKeyboardHeightInPx() does not include the height of that row. Do you know of a way to take it into account as well?Southwestwardly
This only works if u r ready to compromise Layout height change when keyboard appears. right?Uriiah
Clear solution, Thanks.Phelgen
The most elegant one IMHO. Unobtrusive code. what manifest fields does it require? configChanges="orientation|screenSize|keyboardHidden" are the ones that worked for me. Thanks!Zolazoldi
On my Nexus 5 heightDiff = 216 in portret mode without a soft keyboard opened. Maybe because of the bottom bar. On a samsung heightDiff < 100 when no soft keyboard is shown.Deerstalker
I solved this by first determining the normal difference (without soft keyboard).Deerstalker
i am using this solution in fragments based app, and when i replaced the fragment it is getting crashedAngelitaangell
This should be the best answer. working like charm :)Pentavalent
A
35

Some improvements to avoid wrongly detect the visibility of soft keyboard on high density devices:

  1. Threshold of height difference should be defined as 128 dp, not 128 pixels.
    Refer to Google design doc about Metrics and Grid, 48 dp is comfortable size for touch object and 32 dp is minimum for buttons. Generic soft keyboard should include 4 rows of key buttons, so minimum keyboard height should be: 32 dp * 4 = 128 dp, that means threshold size should transfer to pixels by multiply device density. For xxxhdpi devices (density 4), the soft keyboard height threshold should be 128 * 4 = 512 pixels.

  2. Height difference between root view and its visible area:
    root view height - status bar height - visible frame height = root view bottom - visible frame bottom, since status bar height equal to the top of root view visible frame.

    private final String TAG = "TextEditor";
    private TextView mTextEditor;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_editor);
        mTextEditor = (TextView) findViewById(R.id.text_editor);
        mTextEditor.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                isKeyboardShown(mTextEditor.getRootView());
            }
        });
    }
    
    private boolean isKeyboardShown(View rootView) {
        /* 128dp = 32dp * 4, minimum button height 32dp and generic 4 rows soft keyboard */
        final int SOFT_KEYBOARD_HEIGHT_DP_THRESHOLD = 128;
    
        Rect r = new Rect();
        rootView.getWindowVisibleDisplayFrame(r);
        DisplayMetrics dm = rootView.getResources().getDisplayMetrics();
        /* heightDiff = rootView height - status bar height (r.top) - visible frame height (r.bottom - r.top) */
        int heightDiff = rootView.getBottom() - r.bottom;
        /* Threshold size: dp to pixels, multiply with display density */
        boolean isKeyboardShown = heightDiff > SOFT_KEYBOARD_HEIGHT_DP_THRESHOLD * dm.density;
    
        Log.d(TAG, "isKeyboardShown ? " + isKeyboardShown + ", heightDiff:" + heightDiff + ", density:" + dm.density
                + "root view height:" + rootView.getHeight() + ", rect:" + r);
    
        return isKeyboardShown;
    }
    
Authoritarian answered 2/10, 2014 at 0:0 Comment(3)
This deserves to be the accepted answer. Ignoring the density gave me very different results on devices with different form factors but similar pixel sizes. Thanks!Orsola
Excellent. isKeyboardShown() method is what we need. ThanksFidget
It's working in 2020 as well. Perfect answer. I tried all code but on this works perfectly.Involucrum
M
32

Wow, We have Good news Android Geeks. And its time to say goodbye to the old way. First I will add official release note to read and know more about these methods/ classes, and then we will see these amazing methods/ classes

Breaking Note: Do not add these into your release apps, until these classes/ methods are released

How to check keyboard visibility

val insets = ViewCompat.getRootWindowInsets(view)
val isKeyboardVisible = insets.isVisible(Type.ime())

Few other utilities

How to get the height of Keyboard

val insets = ViewCompat.getRootWindowInsets(view)
val keyboardHeight = insets.getInsets(Type.ime()).bottom

How to show/ hide the keyboard

val controller = view.windowInsetsController

// Show the keyboard
controller.show(Type.ime())

// Hide the keyboard
controller.hide(Type.ime())

Note: WindowInsetsController added in API-30, so wait till backward compatible class is not available.

How to listen to keyboard hide/ show event

ViewCompat.setOnApplyWindowInsetsListener(view) { v, insets ->
    val isKeyboardVisible = insets.isVisible(Type.ime())
    if (isKeyboardVisible) {
        // Do it when keyboard is being shown
    } else {
        // Do it when keyboard is hidden
    }

    // Return the insets to keep going down this event to the view hierarchy
    insets
}
Meerkat answered 26/8, 2020 at 10:38 Comment(11)
I have a problem, it says: "Unresolved reference isVisible()", please helpInward
@Inward Are you using developer.android.com/jetpack/androidx/releases/… ?Meerkat
See medium.com/androiddevelopers/… and amazing post for more detailsMeerkat
Ok, now it found the isVisible function. Unfortunately this does not work because it does nothing.. I am using API 21 and adjustresize. I've but the above code in a function and I am calling it from my fragments onViewCreated()Inward
@Inward Could you please add code somewhere so I can look into, or can add a new question, so other can also help?Meerkat
I did: #63874510Inward
@PankajKumar how can I get the keyboard height by using Android jetpack Compose.Meteor
Wow, finally! 10 years later after so much denial that it was needed, wowLatter
Anyone managed to make this work for landscape mode? I found in api 21-29 phones, this only works in portrait? see #69373450Alikee
Doesn't seem to get called consistently with manifest set to adjustPan. Works great with adjustResize though. I ended up changing to adjustResize and just tweaking everything else around that so I could have the listener work correctlyPartial
insets.isVisible(Type.ime()) is always true, even when app is just opened and no keyboard is shownMontpellier
T
8

The idea is, if you need to hide your keyboard and check soft input state at the same time, use the following solution:

public boolean hideSoftInput() {
    InputMethodManager imm = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
    return imm.hideSoftInputFromWindow(mViewPager.getWindowToken(), 0);
}

This method returns true if keyboard was shown before hiding.

Tumer answered 6/12, 2013 at 13:1 Comment(3)
This is the one works without using height and all... Thanks... u saved my time...Diastasis
This should be the accepted answer. All these hacks... smh. The api does not say what the boolean is, so is this a safe method?Mideast
You can pass a ResultReceiver to hideSoftInptFromWindow, and it will give you an explicit answerMideast
C
7

I used a little time to figure this out... I ran it some CastExceptions, but figured out that you can replace you LinearLayout in the layout.xml with the name of the class.

Like this:

<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent"
    xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/llMaster">

<com.ourshoppingnote.RelativeLayoutThatDetectsSoftKeyboard android:background="@drawable/metal_background"
    android:layout_width="fill_parent" android:layout_height="fill_parent"
    android:id="@+id/rlMaster" >
    <LinearLayout android:layout_width="fill_parent"
        android:layout_height="1dip" android:background="@drawable/line"></LinearLayout>

          ....

</com.ourshoppingnote.RelativeLayoutThatDetectsSoftKeyboard>    


</LinearLayout>

That way you do not run into any cast issues.

... and if you don't want to do this on every page, I recommend that you use "MasterPage in Android". See the link here: http://jnastase.alner.net/archive/2011/01/08/ldquomaster-pagesrdquo-in-android.aspx

Calculous answered 9/7, 2011 at 7:39 Comment(5)
Wow be careful about pasting this into your XML if you don't have the same package/class name. Eclipse just decides to freeze and you have to shut it down. Such a professional product. /sLindseylindsley
@SpencerRuport, that's why it's free.Partial
@DoctorOreo - get IntelliJ. It's free and doesn't suck.Stollings
@Stollings - a few months after I posted this I did indeed try out IntelliJ. It's much better, IMO, than Eclipse. All of their products (for the most part) I think are excellent. I've even bought a few.Partial
Sorry for reviving such an old comment thread. I am glad you are using it and enjoying it. I love using IntelliJ as well as AppCode for iOS and PyCharm for Python work. Cheers!Stollings
G
6

Checking the height of elements is not reliable because some keyboards like WifiKeyboard have zero height.

Instead, you can use the callback result of showSoftInput() and hideSoftInput() to check for the status of the keyboard. Full details and example code at

https://rogerkeays.com/how-to-check-if-the-software-keyboard-is-shown-in-android

Guaco answered 20/2, 2012 at 23:50 Comment(0)
K
4

Instead of assuming the difference coding I did something like this, as I dint had menu options in my application.

final View root= findViewById(R.id.myrootview); 
root.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
    public void onGlobalLayout() {
        int heightDiff = root.getRootView().getHeight() - root.getHeight();

        Rect rectgle= new Rect();
        Window window= getWindow();
        window.getDecorView().getWindowVisibleDisplayFrame(rectgle);
        int contentViewTop=                     
          window.findViewById(Window.ID_ANDROID_CONTENT).getTop();
        if(heightDiff <= contentViewTop){
            //Soft KeyBoard Hidden
        }else{
            //Soft KeyBoard Shown
        }
     }
});
Karachi answered 29/9, 2012 at 9:32 Comment(1)
It doesn't work for android:windowSoftInputMode="adjustPan". I wanted that my screen shouldn't get shrinked after soft keyboard appears. Can you please tell any fix so that it works even for adjustPanProject
L
4

You can observe softkeyboard's hide by using activity's decorView.

public final class SoftKeyboardUtil {
    public static final String TAG = "SoftKeyboardUtil";
    public static void observeSoftKeyBoard(Activity activity , final OnSoftKeyBoardHideListener listener){
        final View decorView = activity.getWindow().getDecorView();
        decorView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                Rect rect = new Rect();
                decorView.getWindowVisibleDisplayFrame(rect);
                int displayHight = rect.bottom - rect.top;
                int hight = decorView.getHeight();
                boolean hide = (double)displayHight / hight > 0.8 ;
                if(Log.isLoggable(TAG, Log.DEBUG)){
                    Log.d(TAG ,"DecorView display hight = "+displayHight);
                    Log.d(TAG ,"DecorView hight = "+ hight);
                    Log.d(TAG, "softkeyboard visible = " + !hide);
                }

                listener.onSoftKeyBoardVisible(!hide);

            }
        });
    }



    public interface OnSoftKeyBoardHideListener{
        void onSoftKeyBoardVisible(boolean visible);
    }
}
Laid answered 23/1, 2014 at 5:34 Comment(0)
C
4

There is also solution with system insets, but it works only with API >= 21 (Android L). Say you have BottomNavigationView, which is child of LinearLayout and you need to hide it when keyboard is shown:

> LinearLayout
  > ContentView
  > BottomNavigationView

All you need to do is to extend LinearLayout in such way:

public class KeyboardAwareLinearLayout extends LinearLayout {
    public KeyboardAwareLinearLayout(Context context) {
        super(context);
    }

    public KeyboardAwareLinearLayout(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public KeyboardAwareLinearLayout(Context context,
                                     @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public KeyboardAwareLinearLayout(Context context, AttributeSet attrs,
                                     int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    public WindowInsets onApplyWindowInsets(WindowInsets insets) {
        int childCount = getChildCount();
        for (int index = 0; index < childCount; index++) {
            View view = getChildAt(index);
            if (view instanceof BottomNavigationView) {
                int bottom = insets.getSystemWindowInsetBottom();
                if (bottom >= ViewUtils.dpToPx(200)) {
                    // keyboard is shown
                    view.setVisibility(GONE);
                } else {
                    // keyboard is hidden
                    view.setVisibility(VISIBLE);
                }
            }
        }
        return insets;
    }
}

The idea is that when keyboard is shown, system insets are changed with pretty big .bottom value.

Canon answered 15/2, 2018 at 15:38 Comment(0)
S
4

There's a hidden method can help for this, InputMethodManager.getInputMethodWindowVisibleHeight. But I don't know why it's hidden.

import android.content.Context
import android.os.Handler
import android.view.inputmethod.InputMethodManager

class SoftKeyboardStateWatcher(private val ctx: Context) {
  companion object {
    private const val DELAY = 10L
  }

  private val handler = Handler()
  private var isSoftKeyboardOpened: Boolean = false

  private val height: Int
    get() {
      val imm = ctx.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
      val method = imm.javaClass.getMethod("getInputMethodWindowVisibleHeight")
      method.isAccessible = true
      return method.invoke(imm) as Int
    }

  private val task: Runnable by lazy {
    Runnable {
      start()
      if (!isSoftKeyboardOpened && height > 0) {
        isSoftKeyboardOpened = true
        notifyOnSoftKeyboardOpened(height)
      } else if (isSoftKeyboardOpened && height == 0) {
        isSoftKeyboardOpened = false
        notifyOnSoftKeyboardClosed()
      }
    }
  }

  var listener: SoftKeyboardStateListener? = null

  interface SoftKeyboardStateListener {
    fun onSoftKeyboardOpened(keyboardHeightInPx: Int)
    fun onSoftKeyboardClosed()
  }

  fun start() {
    handler.postDelayed(task, DELAY)
  }

  fun stop() {
    handler.postDelayed({
      if (!isSoftKeyboardOpened) handler.removeCallbacks(task)
    }, DELAY * 10)
  }

  private fun notifyOnSoftKeyboardOpened(keyboardHeightInPx: Int) {
    listener?.onSoftKeyboardOpened(keyboardHeightInPx)
  }

  private fun notifyOnSoftKeyboardClosed() {
    listener?.onSoftKeyboardClosed()
  }
}
Shakti answered 22/5, 2018 at 4:30 Comment(2)
If someone would need this - it works in Xamarin as well, name of the method is exactly the same and needs to be accessed in the same way - through the Class property on the InputMethodManager.Eliott
Be careful using this, it is unsupported API (it's hidden for a reason) and for starters it doesn't work on KitKat.Exogenous
A
3

I found that a combination of @Reuben_Scratton's method along with @Yogesh's method seems to work best. Combining their methods would yield something like this:

final View activityRootView = findViewById(R.id.activityRoot);
activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
  @Override
  public void onGlobalLayout() {
    if (getResources().getConfiguration().keyboardHidden == Configuration.KEYBOARDHIDDEN_NO) { // Check if keyboard is not hidden
       // ... do something here
    }
  }
});
Alvera answered 31/1, 2012 at 21:44 Comment(1)
always Configuration.KEYBOARDHIDDEN_NO.Roesch
S
3

I used a slight variant of Reuban's answer, which proved to be more helpful in certain circumstances, especially with high resolution devices.

final View activityRootView = findViewById(android.R.id.content);
activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(
        new OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                int heightView = activityRootView.getHeight();
                int widthView = activityRootView.getWidth();
                if (1.0 * widthView / heightView > 3) {
                    //Make changes for Keyboard not visible
                } else {
                    //Make changes for keyboard visible
                }
            }
        });
Silber answered 21/2, 2014 at 22:7 Comment(2)
what is this R.id.activityRootHypsometer
instead of creating and using R.id.activityRoot, you can simply use android.R.id.content which is exactly what you need.Cumbrous
P
3

None of these solutions will work for Lollipop as is. In Lollipop activityRootView.getRootView().getHeight() includes the height of the button bar, while measuring the view does not. I've adapted the best/simplest solution above to work with Lollipop.

    final View activityRootView = findViewById(R.id.activityRoot);
activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
  @Override
  public void onGlobalLayout() {
    Rect r = new Rect();
    //r will be populated with the coordinates of your view that area still visible.
    activityRootView.getWindowVisibleDisplayFrame(r);

    int heightDiff = activityRootView.getRootView().getHeight() - (r.bottom - r.top);
    Resources res = getResources();
    // The status bar is 25dp, use 50dp for assurance
    float maxDiff =
        TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, res.getDisplayMetrics());

    //Lollipop includes button bar in the root. Add height of button bar (48dp) to maxDiff
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
      float buttonBarHeight =
          TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 48, res.getDisplayMetrics());
      maxDiff += buttonBarHeight;
    }
    if (heightDiff > maxDiff) { // if more than 100 pixels, its probably a keyboard...
      ...do something here
    }
  }
});
Pompeii answered 18/11, 2014 at 23:1 Comment(1)
Why didn't a similar solution from https://mcmap.net/q/36205/-how-to-check-visibility-of-software-keyboard-in-android work for you and how does your solution differ?Suavity
S
3

I have just encountered a bug while using most of the solutions above that suggest adding a fixed number.

S4 is has a high dpi which resulted in the navigation bar's height being 100px thus my app thinking that the keyboard is open all the time.

So with all the new high res phones being released i believe using a hard coded value is not a good idea for long term.

A better approach that i found after some testing on various screens and devices was to use percentage. Get the difference between decorView and ur app content and afterwards check what is the percentage of that difference. From the stats that i got, most nav bar(regardless of the size, resolution etc..) will take between 3% to 5% of the screen. Where as if the keyboard is open it was taking between 47% to 55% of the screen.

As a conclusion my solution was to check if the diff is more than 10% then i assume its a keyboard open.

Stagecoach answered 4/6, 2015 at 2:40 Comment(0)
I
3

It has been forever in terms of the computer but this question is still unbelievably relevant! So I've taken the above answers and have combined and refined them a bit...

public interface OnKeyboardVisibilityListener {
    void onVisibilityChanged(boolean visible);
}

public final void setKeyboardListener(final OnKeyboardVisibilityListener listener) {
    final View activityRootView = ((ViewGroup) getActivity().findViewById(android.R.id.content)).getChildAt(0);
    activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

        private boolean wasOpened;

    private final Rect r = new Rect();

        @Override
        public void onGlobalLayout() {
            activityRootView.getWindowVisibleDisplayFrame(r);

            int heightDiff = activityRootView.getRootView().getHeight() - (r.bottom - r.top);
            boolean isOpen = heightDiff > 100;
            if (isOpen == wasOpened) {
                logDebug("Ignoring global layout change...");
                return;
            }

            wasOpened = isOpen;
            listener.onVisibilityChanged(isOpen);
        }
    });
}

It works for me.

Inhere answered 16/12, 2016 at 8:24 Comment(0)
P
3

Try this:

final View activityRootView = getWindow().getDecorView().getRootView();
activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        Rect r = new Rect();
        //r will be populated with the coordinates of your view that area still visible.
        activityRootView.getWindowVisibleDisplayFrame(r);

        int heightDiff = activityRootView.getRootView().getHeight() - (r.bottom - r.top);
        if (heightDiff < activityRootView.getRootView().getHeight() / 4 ) { // if more than 100 pixels, its probably a keyboard...
             // ... do something here ... \\
        }
    }
});
Presentable answered 24/10, 2017 at 15:33 Comment(0)
V
3

according to the doc.. https://developer.android.com/reference/androidx/core/view/WindowInsetsCompat

check release note.. https://developer.android.com/jetpack/androidx/releases/core#1.5.0-alpha02

To get the current keyboard visibility, you can use getRootWindowInsets, and then call the isVisible() function, passing in the IME type.

val windowinsetscompat = ViewCompat.getRootWindowInsets(view)
val imeVisible = windowinsetscompat.isVisible(Type.ime())

there is also listener for changes OnApplyWindowInsetsListener

ViewCompat.setOnApplyWindowInsetsListener(view) { v, insets ->
    val imeVisible = insets.isVisible(Type.ime())
}
Vaientina answered 4/9, 2020 at 6:14 Comment(4)
WHERE DOES THE "isVisible" METHOD COME FROM. I have an "unresolved reference". My god I hate android and googleInward
@Inward try adding implementation 'androidx.core:core-ktx:1.5.0-alpha02' in build.gradleVaientina
I've already found it, thank you. But the god-damn function does not work... "OnApplyWindowInsets" is never called... API 21Inward
well if that is the case, I will quit android development for ever.Inward
A
2

Don't make any hard code. Best way is you have to resize your views while on Get Focus on EditText with KeyBord Show. You can do this adding resize property on activity into Manifest file using below code.

android:windowSoftInputMode="adjustResize"

Archiplasm answered 14/10, 2014 at 22:57 Comment(1)
Surprisingly this really works! I had it set to "adjustPan," which didn't do anything. :)Stadtholder
B
2

My answer is basically the same as Kachi's answer, but I wrapped it into a nice helper class to clean up the way it's used throughout my app.

import android.app.Activity;
import android.app.Fragment;
import android.graphics.Rect;
import android.view.View;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;

/**
 * Detects Keyboard Status changes and fires events only once for each change
 */
public class KeyboardStatusDetector {
    KeyboardVisibilityListener visibilityListener;

    boolean keyboardVisible = false;

    public void registerFragment(Fragment f) {
        registerView(f.getView());
    }

    public void registerActivity(Activity a) {
        registerView(a.getWindow().getDecorView().findViewById(android.R.id.content));
    }

    public KeyboardStatusDetector registerView(final View v) {
        v.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                Rect r = new Rect();
                v.getWindowVisibleDisplayFrame(r);

                int heightDiff = v.getRootView().getHeight() - (r.bottom - r.top);
                if (heightDiff > 100) { // if more than 100 pixels, its probably a keyboard...
                    /** Check this variable to debounce layout events */
                    if(!keyboardVisible) {
                        keyboardVisible = true;
                        if(visibilityListener != null) visibilityListener.onVisibilityChanged(true);
                    }
                } else {
                    if(keyboardVisible) {
                        keyboardVisible = false;
                        if(visibilityListener != null) visibilityListener.onVisibilityChanged(false);
                    }
                }
            }
        });

        return this;
    }

    public KeyboardStatusDetector setVisibilityListener(KeyboardVisibilityListener listener) {
        visibilityListener = listener;
        return this;
    }

    public static interface KeyboardVisibilityListener {
        public void onVisibilityChanged(boolean keyboardVisible);
    }
}

You can use this to detect keyboard changes anywhere throughout the app like this:

    new KeyboardStatusDetector()
            .registerFragment(fragment)  //register to a fragment 
            .registerActivity(activity)  //or register to an activity
            .registerView(view)          //or register to a view
            .setVisibilityListener(new KeyboardVisibilityListener() {
                @Override
                public void onVisibilityChanged(boolean keyboardVisible) {
                    if(keyboardVisible) {
                       //Do stuff for keyboard visible
                    }else {
                       //Do stuff for keyboard hidden
                    }
                }
            });

Note: only use one of the "register" calls. They all work the same and are only there for convenience

Ballance answered 17/10, 2014 at 15:48 Comment(0)
P
2

i think this method will help you to find out is keybord is visible or not.

 public Boolean isSoftKeyBoardVisible(){
    InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);

    if (imm.isAcceptingText()) {
        Log.d(TAG,"Software Keyboard was shown");
        return true;
    } else {
        Log.d(TAG,"Software Keyboard was not shown");
        return false;
    }

}
Pabulum answered 27/1, 2015 at 10:38 Comment(1)
always responds that is visibleZacatecas
K
2

you can try this, work great for me:

InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);

if (imm.isAcceptingText()) {
    //Software Keyboard was shown..
} else {
    //Software Keyboard was not shown..
}
Kilovolt answered 16/4, 2015 at 0:12 Comment(2)
Don't use this, it returns true if the keyboard was hidden using back but the view has focus, at least on MarshmallowHarping
always responds that is visibleZacatecas
N
2

I was having difficulty maintaining keyboard state when changing orientation of fragments within a viewpager. I'm not sure why, but it just seems to be wonky and acts differently from a standard Activity.

To maintain keyboard state in this case, first you should add android:windowSoftInputMode = "stateUnchanged" to your AndroidManifest.xml. You may notice, though, that this doesn't actually solve the entire problem -- the keyboard didn't open for me if it was previously opened before orientation change. In all other cases, the behavior seemed to be correct.

Then, we need to implement one of the solutions mentioned here. The cleanest one I found was George Maisuradze's--use the boolean callback from hideSoftInputFromWindow:

InputMethodManager imm = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
return imm.hideSoftInputFromWindow(mViewPager.getWindowToken(), 0);

I stored this value in my Fragment's onSaveInstanceState method and retrieved it onCreate. Then, I forcibly showed the keyboard in onCreateView if it had a value of true (it returns true if the keyboard is visible before actually hiding it prior to the Fragment destruction).

Nowak answered 21/8, 2017 at 0:13 Comment(0)
T
1

Here's my solution, and it works. Instead of looking for pixel size just check that the height of the content view has changed or not:

// Scroll to the latest comment whenever the keyboard is shown
commentsContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

        private int oldHeight;

        @Override
        public void onGlobalLayout() {
            int newHeight = commentsContent.getMeasuredHeight();
            if (newHeight < oldHeight) {
                // Check for the keyboard showing in case the height difference
                // is a result of orientation change
                if (isSoftKeyboardShowing(CommentsActivity.this)) {
                    // Keyboard is showing so scroll to the latest comment
                    scrollToLatestComment();
                }
            }
            oldHeight = newHeight;
        }

    });


public static boolean isSoftKeyboardShowing(Activity activity) {
    InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
    return inputMethodManager.isActive();
}
Tomchay answered 3/7, 2014 at 16:4 Comment(1)
inputMethodManager.isActive() is always returning true for me, regardless of whether the keyboard is up or notCasarez
T
1

There is a direct method to find this out. And, it does not require any Layout changes.
So, it works in immersive fullscreen mode, too.

The trick is that you try to hide or show the soft keyboard and capture the result of that try.
No panic, this does not really show or hide the keyboard. We just ask for the state.

To stay up-to-date, you can simply repeat the operation, e.g. every 200 milliseconds, using a Handler.

You find an implementation here: https://mcmap.net/q/36354/-how-do-i-detect-if-software-keyboard-is-visible-on-android-device-or-not

Tootle answered 19/12, 2014 at 15:32 Comment(0)
I
1

This solution may re-opens the keyboard but it works.

InputMethodManager inputManager = ( (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE) );

private boolean isKeyboardShowing() {

    boolean isKeyboardShowing = inputManager.hideSoftInputFromWindow(irrelevantView.getWindowToken(), 0);
    if (isKeyboardShowing) {
        inputManager.showSoftInput(this.getCurrentFocus(), 0);
    }
    return isKeyboardShowing;
}
Indefensible answered 23/6, 2015 at 14:49 Comment(0)
F
1

You can use InputMethodManager.isActive method that returns true if the keyboard is visible:

    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.isActive();

You can also see if the keyboard is active in a specific view:

    imm.isActive(View v);
Friarbird answered 15/1, 2016 at 18:0 Comment(0)
T
1

After understanding some of the issues with different resolutions, I decided to use a relative size. As I noticed the difference between visible and hidden states is about 30%. So I decided to replace 128 PX with 0.3.

And I added this class listener to notify of any change.

Here is my version

import android.app.*;
import android.graphics.*;
import android.view.*;

public class SoftKeyboardState {
  public static final int HIDDEN = 0, VISIBLE = 1;
  private OnKeyboardStateChangedListener listener;
  private View decorView;

  public SoftKeyboardState(Activity activity) {
    this.decorView = activity.findViewById(android.R.id.content);
    initKeyboardListener();
  }

  private void initKeyboardListener() {
    decorView.getViewTreeObserver().addOnGlobalLayoutListener(
      new ViewTreeObserver.OnGlobalLayoutListener(){
        private final Rect windowVisibleDisplayFrame = new Rect();
        private int lastVisibleDecorViewHeight;

        @Override
        public void onGlobalLayout() {
          decorView.getWindowVisibleDisplayFrame(windowVisibleDisplayFrame);
          final int visibleDecorViewHeight = windowVisibleDisplayFrame.height();

          if (lastVisibleDecorViewHeight != 0) {
            if ((lastVisibleDecorViewHeight > visibleDecorViewHeight) && (lastVisibleDecorViewHeight / visibleDecorViewHeight >= 0.3f)) {
              // visible
              if (listener != null)listener.onKeyboardStateChanged(VISIBLE);
            } else if ((lastVisibleDecorViewHeight < visibleDecorViewHeight) && (visibleDecorViewHeight / lastVisibleDecorViewHeight >= 0.3f)) {
              // hidden
              if (listener != null)listener.onKeyboardStateChanged(HIDDEN);
            }
          }
          lastVisibleDecorViewHeight = visibleDecorViewHeight;
        }
      });
  }

  public void setOnKeyboardStateChangedListener(OnKeyboardStateChangedListener listener) {
    this.listener = listener;
  }

  public interface OnKeyboardStateChangedListener {
    public void onKeyboardStateChanged(int state);
  }
}
Theater answered 13/11, 2017 at 8:2 Comment(1)
In your manifest, you need to set android:windowSoftInputMethod="adjustResize"Theater
C
1

99% of solutions here are based on probability of IME WINDOW SIZE and each such solution is a sh... worth!

because:

  1. OVERLAYS - from User apps or System apps
  2. IME have no MINIMUM SIZE it can take 100% of window size and can be so thin as imagination of developer implementation :)
  3. MODAL windows / MULTI windows
  4. and many many more like no knowledge of IPC (eg: foreign window or its content detection)

so guessing it's IME is always wrong - don't guess be sure !!!

@kevin-du is best solution wright now as its query IMM for IME height - but as it said the method is hidden API so using it could be dangerous in the way of getting wrong "false negative results" - by wrong dev usage.

Crybaby answered 5/10, 2019 at 13:46 Comment(0)
L
0

Reuben Scratton's new answer (calculate the HeightDiff int heightDiff = activityRootView.getRootView().getHeight() - activityRootView.getHeight(); ) will not work in activity if you set the translucent status bar mode.

if you use translucent status bar , activityRootView.getHeight() will never change weather the soft keyboard is visible. it will always return the height of activity and status bar.

For example, Nexus 4, Android 5.0.1, set android:windowTranslucentStatus to true, it will return 1184 forever, even the ime have opend. If you set android:windowTranslucentStatus to false, it will return Height correctly, if ime invisible,it return 1134(not include the status bar)。close the ime, it will return 5xx maybe (depends on ime's height)

I don't know weather this is a bug, I've try on 4.4.4 and 5.0.1, the result is same.

So, up to now, the second most agreed answer, Kachi's solution will be the most safe way to calcute the height of ime. Here's a copy:

final View activityRootView = findViewById(R.id.activityRoot);
activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new        OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Rect r = new Rect();
//r will be populated with the coordinates of your view that area still visible.
activityRootView.getWindowVisibleDisplayFrame(r);

int heightDiff = activityRootView.getRootView().getHeight() - (r.bottom - r.top);
if (heightDiff > 100) { // if more than 100 pixels, its probably a keyboard...
    ... do something here
    }
 }
}); 
Luvenialuwana answered 24/3, 2015 at 12:45 Comment(0)
T
0

A method that doesn't need a LayoutListener

In my case, I would like to save the state of the keyboard before replacing my Fragment. I call the method hideSoftInputFromWindow from onSaveInstanceState, which closes the keyboard and returns me whether the keyboard was visible or not.

This method is straightforward but may change the state of your keyboard.

Tempura answered 26/5, 2015 at 8:24 Comment(0)
H
0

I know that this is a old post but I think this is the simplest approach that I know and my test device is Nexus 5. I haven't tried it in other devices. Hope that others will share their approach if they find my code is not good :)

public static boolean isKeyboardShown(Context context, View view) {
        if (context == null || view == null) {
            return false;
        }
        InputMethodManager imm = (InputMethodManager) context
                .getSystemService(Context.INPUT_METHOD_SERVICE);
        return imm.hideSoftInputFromWindow(view.getWindowToken(), 0); 
}

imm.hideSoftInputFromWindow returns boolean.

Thanks,

Haupt answered 20/7, 2015 at 8:17 Comment(0)
L
0
if (keyopen())
{
                InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY,0);            
}

The above function is what I use to check if a Keyboard is visible. If it is, then I close it.

Below shows the two methods required.

First, define the workable Window height in onCreate.

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

//  add to onCreate method
    Rect rectgle= new Rect();
    Window window= getWindow();
    window.getDecorView().getWindowVisibleDisplayFrame(rectgle);
    sheight= rectgle.bottom;
//

} 

Then, add a boolean method that gets the Window height at that instance. If it does not match the original (assuming you are not changing it along the way...) then, the keyboard is open.

public boolean keyopen()
{
    Rect rectgle= new Rect();
    Window window= getWindow();
    window.getDecorView().getWindowVisibleDisplayFrame(rectgle);
    int curheight= rectgle.bottom;

    if (curheight!=sheight)
    {
        return true;
    }
    else
    {
        return false;
    }
}

Frotz!

Lithic answered 11/8, 2015 at 18:58 Comment(0)
C
0

I know how exact you can determine if keyboard is hidden or not.

public int getStatusBarHeight() {
    int result = 0;
    int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
    if (resourceId > 0) {
        result = getResources().getDimensionPixelSize(resourceId);
    }
    return result;
}

public int getNavigationBarHeight() {
    int result = 0;
    int resourceId = getResources().getIdentifier("navigation_bar_height", "dimen", "android");
    if (resourceId > 0) {
        result = getResources().getDimensionPixelSize(resourceId);
    }
    return result;
}

public boolean isKeyboardHidden() {
    int delta = mRootView.getRootView().getHeight() - mRootView.getHeight() - getNavigationBarHeight() - getStatusBarHeight()
            - getSupportActionBar().getHeight();
    return delta <= 0;
}

This works for tablets. When navigationbar is shown horizontally.

Congregate answered 30/9, 2015 at 6:15 Comment(0)
E
0

The solution provided by Reuben Scratton and Kachi seems to rely on the pixel density of the devices, if you have a high density device the height difference can be bigger than 100 even with the keyboard down. A little work around that would be to see the initial height difference (with keyboard down) and then compare with the current difference.

boolean isOpened = false;
int firstHeightDiff = -1;

public void setListenerToRootView(){
    final View activityRootView = getActivity().getWindow().getDecorView().findViewById(android.R.id.content);
    Rect r = new Rect();
    activityRootView.getWindowVisibleDisplayFrame(r);
    firstHeightDiff = activityRootView.getRootView().getHeight() - (r.bottom - r.top);
    activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            if (isAdded()) {
                Rect r = new Rect();
                activityRootView.getWindowVisibleDisplayFrame(r);
                int heightDiff = activityRootView.getRootView().getHeight() - (r.bottom - r.top);
                isOpened = heightDiff>firstHeightDiff+100;
                if (isAdded())
                    if(isOpened) {
                        //TODO stuff for when it is up
                    } else {
                        //TODO stuf for when it is down
                    }
            }
        }
    });
}
Endogen answered 11/3, 2016 at 19:7 Comment(0)
P
0

Here is a workaround to know if softkeyboard is visible.

  1. Check for running services on the system using ActivityManager.getRunningServices(max_count_of_services);
  2. From the returned ActivityManager.RunningServiceInfo instances, check clientCount value for soft keyboard service.
  3. The aforementioned clientCount will be incremented every time, the soft keyboard is shown. For example, if clientCount was initially 1, it would be 2 when the keyboard is shown.
  4. On keyboard dismissal, clientCount is decremented. In this case, it resets to 1.

Some of the popular keyboards have certain keywords in their classNames:

Google AOSP = IME
Swype = IME
Swiftkey = KeyboardService
Fleksy = keyboard
Adaptxt = IME (KPTAdaptxtIME)
Smart = Keyboard (SmartKeyboard)

From ActivityManager.RunningServiceInfo, check for the above patterns in ClassNames. Also, ActivityManager.RunningServiceInfo's clientPackage=android, indicating that the keyboard is bound to system.

The above mentioned information could be combined for a strict way to find out if soft keyboard is visible.

Pathetic answered 1/6, 2016 at 12:52 Comment(0)
M
0

This code works great nice

use this class for root view:

public class KeyboardConstraintLayout extends ConstraintLayout {

private KeyboardListener keyboardListener;
private EditText targetEditText;
private int minKeyboardHeight;
private boolean isShow;

public KeyboardConstraintLayout(Context context) {
    super(context);
    minKeyboardHeight = getResources().getDimensionPixelSize(R.dimen.keyboard_min_height);
}

public KeyboardConstraintLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
    minKeyboardHeight = getResources().getDimensionPixelSize(R.dimen.keyboard_min_height);
}

public KeyboardConstraintLayout(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    minKeyboardHeight = getResources().getDimensionPixelSize(R.dimen.keyboard_min_height);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    if (!isInEditMode()) {
        Activity activity = (Activity) getContext();
        @SuppressLint("DrawAllocation")
        Rect rect = new Rect();
        getWindowVisibleDisplayFrame(rect);

        int statusBarHeight = rect.top;
        int keyboardHeight = activity.getWindowManager().getDefaultDisplay().getHeight() - (rect.bottom - rect.top) - statusBarHeight;

        if (keyboardListener != null && targetEditText != null && targetEditText.isFocused()) {
            if (keyboardHeight > minKeyboardHeight) {
                if (!isShow) {
                    isShow = true;
                    keyboardListener.onKeyboardVisibility(true);
                }
            }else {
                if (isShow) {
                    isShow = false;
                    keyboardListener.onKeyboardVisibility(false);
                }
            }
        }
    }
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

public boolean isShowKeyboard() {
    return isShow;
}

public void setKeyboardListener(EditText targetEditText, KeyboardListener keyboardListener) {
    this.targetEditText = targetEditText;
    this.keyboardListener = keyboardListener;
}

public interface KeyboardListener {
    void onKeyboardVisibility (boolean isVisible);
}

}

and set keyboard listener in activity or fragment:

    rootLayout.setKeyboardListener(targetEditText, new KeyboardConstraintLayout.KeyboardListener() {
    @Override
    public void onKeyboardVisibility(boolean isVisible) {

    }
});
Municipality answered 22/5, 2018 at 16:14 Comment(0)
H
0

Maybe this will help you:

InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
Holeandcorner answered 7/3, 2019 at 10:28 Comment(1)
While this code snippet may solve the question, including an explanation really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. Please also try not to crowd your code with explanatory comments, this reduces the readability of both the code and the explanations!Crypt
S
0

Referring to this answer by @TacB0sS I have developed one class in Kotlin. Hope this will be helpful. Let me know if it requires some improvement.

class KeyboardVisibilityObserver(val layRootContainer: View?, val keyboardVisibilityListener: KeyboardVisibilityListener?) {
    var isKeyboardOpen = false
        private set

    private var keyBoardObserver = object : ViewTreeObserver.OnGlobalLayoutListener {

        private val DefaultKeyboardDP = 100

        // Lollipop includes button bar in the root. Add height of button bar (48dp) to maxDiff
        private val EstimatedKeyboardDP = DefaultKeyboardDP + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) 48 else 0

        private val r = Rect()

        override fun onGlobalLayout() {
            if (layRootContainer != null) {
                // Convert the dp to pixels.
                val estimatedKeyboardHeight = TypedValue
                        .applyDimension(TypedValue.COMPLEX_UNIT_DIP, EstimatedKeyboardDP.toFloat(), layRootContainer.resources.displayMetrics).toInt()

                // Conclude whether the keyboard is shown or not.
                layRootContainer.getWindowVisibleDisplayFrame(r)
                val heightDiff = layRootContainer.rootView.height - (r.bottom - r.top)
                val isShown = heightDiff >= estimatedKeyboardHeight

                if (isShown == isKeyboardOpen) {
                    //  Log.d("Keyboard state", "Ignoring global layout change...");
                    return
                }

                isKeyboardOpen = isShown

                keyboardVisibilityListener?.onKeyboardVisibilityChanged(isKeyboardOpen)
            }
        }
    }

    init {
        layRootContainer?.viewTreeObserver?.addOnGlobalLayoutListener(keyBoardObserver)
    }

    // call this in onDestroy
    fun removeObserver(){
        layRootContainer?.viewTreeObserver?.removeOnGlobalLayoutListener(keyBoardObserver)
    }

    interface KeyboardVisibilityListener {
        fun onKeyboardVisibilityChanged(isKeyboardOpen: Boolean)
    }
}
Stucker answered 12/11, 2019 at 20:58 Comment(0)
K
0

In addition to the correct answer I had to add this at the end of the onCreateView when using a webview inside a fragment.

getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);

May be is because I am running a Webview inside a fragment or maybe a new behavior on API 30, my issue was that the height of the fragment was never altered even if the keyboard was being shown.

So for Fragment the entire code should be

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = super.onCreateView(inflater, container, savedInstanceState);
    //mWebView.postUrl("https://www.google.com/");
    final View activityRootView = view;
    layoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            Rect r = new Rect();
            //r will be populated with the coordinates of your view that area still visible.
            activityRootView.getWindowVisibleDisplayFrame(r);
            // This variable was created only for Debug purposes and 
            // to see the height change when clicking on a field inside mWebView
            int screenHeight = activityRootView.getRootView().getHeight();
            Log.d("onGlobalLayout", "rect: " + r.toString());
            Log.d("onGlobalLayout", "screenHeight: " + screenHeight);

            //The difference on the heights from bottom to top and on the root height
            int heightDiff = screenHeight - (r.bottom - r.top);
            Log.d("onGlobalLayout", "heightDiff: " + heightDiff);

            //I suggest to put 250 on resources to have better order
            float dpx = dpToPx(getActivity(), 250);

            if (previousHeightDiff != heightDiff) {
                if (heightDiff > dpx) {
                    isSoftKeyboardPresent = true;
                } else {
                    isSoftKeyboardPresent = false;
                }
                previousHeightDiff = heightDiff;
            }
        }
    };
    activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(layoutListener);
    getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
    return view;
}

private static float dpToPx(Context context, float valueInDp) {
    DisplayMetrics metrics = context.getResources().getDisplayMetrics();
    return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, valueInDp, metrics);
}
Kassiekassity answered 10/2, 2021 at 22:19 Comment(0)
M
0

This is probably not suitable for production because it will open the keyboard. Note that the boolean returned by similar functions is not specified in the API and are therefore unreliable. Refer to the documentation here...

https://developer.android.com/reference/android/view/inputmethod/InputMethodManager#showSoftInput(android.view.View,%20int,%20android.os.ResultReceiver)

public boolean showSoftInput (View view, 
            int flags, 
            ResultReceiver resultReceiver)

Note that this method takes a ResultReceiver. It can get the results: RESULT_UNCHANGED_SHOWN, RESULT_UNCHANGED_HIDDEN, RESULT_SHOWN, or RESULT_HIDDEN. If you get RESULT_UNCHANGED_SHOWN, the keyboard was visible. If you need it to stay closed if it was closed, you will need to close it.

Mideast answered 28/2, 2021 at 4:21 Comment(0)
R
0

View#setOnApplyWindowInsetsListener can be used to get window insets callback

public void setOnApplyWindowInsetsListener(OnApplyWindowInsetsListener listener) {
    getListenerInfo().mOnApplyWindowInsetsListener = listener;
}

//OnApplyWindowInsetsListener
public WindowInsets onApplyWindowInsets(View v, WindowInsets insets);

And boolean keyboardVisible = insets.isVisible(WindowInsets.Type.ime()) can give the visibility state.

Rothman answered 15/6, 2021 at 5:17 Comment(0)
L
-3

The InputMethodManager has information about the soft keyboard. You get it from an activity via:

((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE))

You might play around with that to see what it can tell you. You can use it to show or hide the soft input...

Ligate answered 27/1, 2010 at 23:49 Comment(1)
I have looked at InputMethodManager before and unfortunately I couldn't find anything that could tell me if keyb. is open or hidden.Collocation

© 2022 - 2024 — McMap. All rights reserved.