Android show softkeyboard with showSoftInput is not working?
Asked Answered
W

17

43

I have created a trivial application to test the following functionality. When my activity launches, it needs to be launched with the softkeyboard open.

My code does not work?!

I have tried various "state" settings in the manifest and different flags in the code to the InputMethodManager (imm).

I have included the setting in the AndroidManifest.xml and explicitly invoked in the onCreate of the only activity.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.mycompany.android.studyIme"
      android:versionCode="1"
      android:versionName="1.0">
    <uses-sdk android:minSdkVersion="7" />

    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".StudyImeActivity"
                  android:label="@string/app_name" 
                  android:windowSoftInputMode="stateAlwaysVisible">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>
</manifest>

... the main layout (main.xml) ...

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <TextView  
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:text="@string/hello"
        />
    <EditText
        android:id="@+id/edit_sample_text"
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content"
        android:hint="@string/hello"
        android:inputType="textShortMessage"
    />
</LinearLayout>

... and the code ...

public class StudyImeActivity extends Activity {
    private EditText mEditTextStudy;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mEditTextStudy = (EditText) findViewById(R.id.edit_study);
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.showSoftInput(mEditTextStudy, InputMethodManager.SHOW_FORCED);
    }
}
Whiteside answered 1/4, 2011 at 23:59 Comment(2)
Hmm ... I just tried this, with just the default "HelloWorld" activity (i.e., not including the SHOW_FORCED code), on my Sprint LG Optimus phone and it worked as expected. Is it possible that the feature is device (OS installed) dependent?? I will test again on my other devices (HTC, G2 and MyTouch) when I get home.Whiteside
Please see my reply here, I've tried all the below mentioned techniques, but this worked: https://mcmap.net/q/76388/-forcing-the-soft-keyboard-openThirion
W
19

This is so subtle, that it is criminal. This works on the phones that do NOT have a hard, slide-out keyboard. The phones with a hard keyboard will not open automatically with this call. My LG and old Nexus One do not have a keyboard -- therefore, the soft-keyboard opens when the activity launches (that is what I want), but the MyTouch and HTC G2 phones that have slide-out keyboards do not open the soft keyboard until I touch the edit field with the hard keyboard closed.

Whiteside answered 2/4, 2011 at 22:41 Comment(3)
NOTE: I have done a lot of experimenting with the EditText and the InputMethodManager in an attempt to force the soft-keyboard to open when the device has a hard keyboard with no success.Whiteside
For anyone doing Xamarin development in Visual Studio, in the AVD Manager you can edit you AVD and there is a setting labelled "Hardware keyboard present". Unchecking this will allow the soft input to display.Ardeha
@arbitur -- you can relax. This is like a hundred years ago in Google-years. (did you even know that anyone even manufactured slide-out, hard keyboards --haha). Way back then, i was the only one interested in the problem and solution, so I was trying to be complete.Whiteside
B
64

When the activity launches It seems that the keyboard is initially displayed but hidden by something else, because the following works (but is actually a dirty work-around):

First Method

InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
editText.postDelayed(new Runnable()
{
    @Override
    public void run()
    {
        editText.requestFocus();
        imm.showSoftInput(editText, 0);
    }
}, 100);

Second method

in onCreate to launch it on activity create

new Handler().postDelayed(new Runnable() {
    @Override
    public void run() 
    {
    //  InputMethodManager inputMethodManager=(InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
    //    inputMethodManager.toggleSoftInputFromWindow(EnterYourViewHere.getApplicationWindowToken(), InputMethodManager.SHOW_FORCED, 0);

        if (inputMethodManager != null)
        {
            inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED,0);
        } 
    }
}, 200);

Third Method ADD given code to activity tag in Manifest. It will show keyboard on launch, and set the first focus to your desire view.

android:windowSoftInputMode="stateVisible"
Bair answered 18/12, 2014 at 7:4 Comment(4)
I have the same problem. Calling showSoftInput() immediately has no visible result, but posting it on a delay causes the keyboard to display correctly. I initially thought, like you, that it was being shown and then promptly hidden by something else. After a little digging though, I found that I could pass in a ResultReceiver and log the results. When I post showSoftInput() on a delay, the result code returned to my receiver is RESULT_SHOWN. When I don't use the delay, my receiver is not called at all. Now I suspect rather than being hidden, it is not showing it at all for some reason.Haemal
Thanks man. Used the first method while fixing issue with the keyboard not showing the first time a dialog fragment (with an EditText) launches.Cene
Another up-vote for calling postDelayed vs. post - there's likely some other default, hidden functionality which is causing the keyboard to be hidden first. Showing and hiding the keyboard is the most massively broken API in existence.Stiltner
Your First Method works well when programatically switching layouts and opening keyboards. It does seem that some other process is blocking showSoftInput() from functioning correctly.Parlormaid
M
24

Hey I hope you are still looking for the answer as I found it when testing out my code. here is the code:

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

imm.toggleSoftInput(0, 0);

Here is my question that was answered: android - show soft keyboard on demand

Mateo answered 29/6, 2011 at 0:58 Comment(1)
Brute force to the rescue! (We have an in-house application and support only one tablet, so our Standard Operating Procedure is to use that soft keyboard, so we have no reason to make the user wait for it)Presence
T
21

This worked with me on a phone with hard keyboard:

editText1.requestFocus();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
          imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,0);
Thinskinned answered 22/2, 2013 at 1:55 Comment(1)
great I was missing requestFocus() which was stopping the keyboard to be shown for first time.Pietism
W
19

This is so subtle, that it is criminal. This works on the phones that do NOT have a hard, slide-out keyboard. The phones with a hard keyboard will not open automatically with this call. My LG and old Nexus One do not have a keyboard -- therefore, the soft-keyboard opens when the activity launches (that is what I want), but the MyTouch and HTC G2 phones that have slide-out keyboards do not open the soft keyboard until I touch the edit field with the hard keyboard closed.

Whiteside answered 2/4, 2011 at 22:41 Comment(3)
NOTE: I have done a lot of experimenting with the EditText and the InputMethodManager in an attempt to force the soft-keyboard to open when the device has a hard keyboard with no success.Whiteside
For anyone doing Xamarin development in Visual Studio, in the AVD Manager you can edit you AVD and there is a setting labelled "Hardware keyboard present". Unchecking this will allow the soft input to display.Ardeha
@arbitur -- you can relax. This is like a hundred years ago in Google-years. (did you even know that anyone even manufactured slide-out, hard keyboards --haha). Way back then, i was the only one interested in the problem and solution, so I was trying to be complete.Whiteside
M
12

This answer maybe late but it works perfectly for me. Maybe it helps someone :)

public void showSoftKeyboard(View view) {
    if (view.requestFocus()) {
        InputMethodManager imm = (InputMethodManager)
                getSystemService(Context.INPUT_METHOD_SERVICE);
        boolean isShowing = imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
        if (!isShowing)
            getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
    }
}

Depends on you need, you can use other flags

InputMethodManager.SHOW_FORCED
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
Mudpack answered 22/6, 2016 at 12:20 Comment(1)
Requesting focus before showing the keyboard works well 👌🏼 (I had it the other way around)Serpent
F
10

Showing Soft Keyboard is a big problem. I searched a lot to come to a final conclusion. Thanks to this answer which gave a number of clues: https://mcmap.net/q/76390/-android-keyboard-not-appearing-even-when-explicitly-requested

Problem:

Normally we call showSoftInput as soon as we initialize the views. In Activities, this is mostly in onCreate, in Fragments onCreateView. In order to show the keyboard, IMM needs to have the focsedView as active. This can be checked using isActive(view) method of IMM. If we call showSoftInput while the views are being created, there is a good chance that the view won't be active for IMM. That is the reason why sometimes a 50-100 ms delayed showSoftInput is useful. However, that still does not guarantee that after 100 ms the view will become active. So in my understanding, this is again a hack.

Solution:

I use the following class. This keeps running every 100 ms until the keyboard has been successfully shown. It performs various checks in each iteration. Some checks can stop the runnable, some post it after 100 ms.

public class KeyboardRunnable extends Runnable
{
    // ----------------------- Constants ----------------------- //
    private static final String TAG = "KEYBOARD_RUNNABLE";

    // Runnable Interval
    private static final int INTERVAL_MS = 100;

    // ----------------------- Classes ---------------------------//
    // ----------------------- Interfaces ----------------------- //
    // ----------------------- Globals ----------------------- //
    private Activity parentActivity = null;
    private View targetView = null;

    // ----------------------- Constructor ----------------------- //
    public KeyboardRunnable(Activity parentActivity, View targetView)
    {
        this.parentActivity = parentActivity;
        this.targetView = targetView;
    }

    // ----------------------- Overrides ----------------------- //
    @Override
    public void run()
    {
        // Validate Params
        if ((parentActivity == null) || (targetView == null))
        {
            Dbg.error(TAG, "Invalid Params");
            return;
        }

        // Get Input Method Manager
        InputMethodManager imm = (InputMethodManager) parentActivity.getSystemService(Context.INPUT_METHOD_SERVICE);

        // Check view is focusable
        if (!(targetView.isFocusable() && targetView.isFocusableInTouchMode()))
        {
            Dbg.error(TAG, "Non focusable view");
            return;
        }
        // Try focusing
        else if (!targetView.requestFocus())
        {
            Dbg.error(TAG, "Cannot focus on view");
            Post();
        }
        // Check if Imm is active with this view
        else if (!imm.isActive(targetView))
        {
            Dbg.error(TAG, "IMM is not active");
            Post();
        }
        // Show Keyboard
       else if (!imm.showSoftInput(targetView, InputMethodManager.SHOW_IMPLICIT))
        {
            Dbg.error(TAG, "Unable to show keyboard");
            Post();
        }
    }

    // ----------------------- Public APIs ----------------------- //
    public static void Hide(Activity parentActivity)
    {
        if (parentActivity != null)
        {
            InputMethodManager imm = (InputMethodManager) parentActivity.getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(parentActivity.findViewById(android.R.id.content).getWindowToken(), 0);
        }
        else
        {
            Dbg.error(TAG, "Invalid params to hide keyboard");
        }
    }

    // ----------------------- Private APIs ----------------------- //
    protected void Post()
    {
        // Post this aftr 100 ms
        handler.postDelayed(this, INTERVAL_MS);
    }
}

To use this, Just create an instance of this class. Pass it the parent activity and the targetView which would have keyboard input and focus afterwards. Then post the instance using a Handler.

Footwear answered 20/4, 2017 at 10:14 Comment(0)
W
7

Following worked for me:

    mEditTextStudy.requestFocus();
    mEditTextStudy.post(
            new Runnable() {
                @Override
                public void run() {
                    InputMethodManager imm =
                            (InputMethodManager)
                                    getActivity()
                                            .getSystemService(Context.INPUT_METHOD_SERVICE);
                    if (imm != null) {
                        imm.showSoftInput(mEditTextStudy, SHOW_FORCED);
                    }
                }
            });
Weatherwise answered 16/11, 2018 at 10:7 Comment(0)
J
7

For those who want a less hacky, and as-short-as-it-gets reliable solution to show the keyboard in 2022, I found this blog Showing the Android Keyboard Reliably with an answer that works really well for me, and it is less hacky than the postDelay 100ms as it utilizes OnWindowFocusChangeListener to do the trick.

It is really simple to use (something like this should be built in By Google!):

editText.focusAndShowKeyboard()

Add this extension method in Kotlin to use this on any View!

fun View.focusAndShowKeyboard() {
   /**
    * This is to be called when the window already has focus.
    */
   fun View.showTheKeyboardNow() {
       if (isFocused) {
           post {
               // We still post the call, just in case we are being notified of the windows focus
               // but InputMethodManager didn't get properly setup yet.
               val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
               imm.showSoftInput(this, InputMethodManager.SHOW_IMPLICIT)
           }
       }
   }

   requestFocus()
   if (hasWindowFocus()) {
       // No need to wait for the window to get focus.
       showTheKeyboardNow()
   } else {
       // We need to wait until the window gets focus.
       viewTreeObserver.addOnWindowFocusChangeListener(
           object : ViewTreeObserver.OnWindowFocusChangeListener {
               override fun onWindowFocusChanged(hasFocus: Boolean) {
                   // This notification will arrive just before the InputMethodManager gets set up.
                   if (hasFocus) {
                       [email protected]()
                       // It’s very important to remove this listener once we are done.
                       viewTreeObserver.removeOnWindowFocusChangeListener(this)
                   }
               }
           })
   }
}

You may think but why all these code when calling showSoftInput works during my testing? What I think it works for some people but not for others is because most people tested that in a normal activity or fragment, while the ones who reported not working (like me) were probably testing it in a dialog fragment or some sort. So this solution is more fool proof and can be used anywhere.

Japonica answered 23/3, 2022 at 13:5 Comment(4)
Android 12 (at least on Pixel 7): This doesn't work. It broke because of Android 12 and now this answer also doesn't change anything. Seems like onWindowFocusChanged just never gets called. Not sure how to proceed to fix this as I haven'f found any answer yet. Just 1 IssueTracker postGuth
One concern is that what if, 1. after "requestFocus()", 2. you enter if-statement, and gets hasWindowFocus() false 3. but before focus change listener is added, the view gets focused in this scenario, the listener misses the event, and the keyboard will not open at all.Illinois
As an alternative, what if we 1. add focus listener 2. request for focus in this case, event will never be missed. there we be some performance loss, but it's unlikely that users would notice a few miliseconds of delayIllinois
This is the correct and reliable way to do it, no delays and race conditions!Casemate
F
1

My code had the toggle in it but not postDelayed. I had tried postDelayed for the showSoftInput without success and I have since tried your suggested solution. I was about to discard it as yet another failed potential solution until I decided to increase the delay time. It works for me all the way down to 200 ms at which point it doesn't work, at least not on the physical phones. So before you poor android developers ditch this answer, try upping the delay for a successful solution. It may pay to add a bit for older slower phones. Thanks heaps, was working on this one for hours.

Fucus answered 5/8, 2015 at 17:3 Comment(0)
M
1

Solution for Xamarin developers (_digit1 == EditText):

        var focussed = _digit1.RequestFocus();
        if (focussed)
        {
            Window.SetSoftInputMode(SoftInput.StateAlwaysVisible);
            var imm = (InputMethodManager)GetSystemService(InputMethodService);
            imm.ToggleSoftInput(ShowFlags.Forced, 0);
        }
Maighdiln answered 12/8, 2018 at 12:29 Comment(0)
M
1

Here is the modified version of Siddharth Garg's answer. It work's 100% of the time.

import android.content.Context;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.util.Log;
import android.view.View;
import android.view.inputmethod.InputMethodManager;

public class SoftInputService implements Runnable {

    private static final String TAG = SoftInputService.class.getSimpleName();

    private static final int INTERVAL_MS = 100;

    private Context context;
    private View targetView;
    private Handler handler;

    public SoftInputService(Context context, View targetView) {
        this.context = context;
        this.targetView = targetView;
        handler = new Handler(Looper.getMainLooper());
    }

    @Override
    public void run() {
        if (context == null || targetView == null) {
            return;
        }

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

        if (!targetView.isFocusable() || !targetView.isFocusableInTouchMode()) {
            Log.d(TAG,"focusable = " + targetView.isFocusable() + ", focusableInTouchMode = " + targetView.isFocusableInTouchMode());
            return;

        } else if (!targetView.requestFocus()) {
            Log.d(TAG,"Cannot focus on view");
            post();

        } else if (!imm.showSoftInput(targetView, InputMethodManager.SHOW_IMPLICIT)) {
            Log.d(TAG,"Unable to show keyboard");
            post();
        }
    }

    public void show() {
        handler.post(this);
    }

    public static void hide(Context context, IBinder windowToekn) {
        InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(windowToekn, 0);
    }

    protected void post() {
        handler.postDelayed(this, INTERVAL_MS);
    }
}

Usage:

// To show the soft input
new SoftInputService(context, theEditText).show();
// To hide the soft input
SoftInputService.hide(context, theEditText.getWindowToken());
Marry answered 18/11, 2019 at 4:13 Comment(0)
N
1

Similar problem but different solution so posting in case it is useful to others.

The problem was not with my code and use of:

inputMethodManager.showSoftInput(kbdInput, InputMethodManager.SHOW_IMPLICIT);

The problem related to that as of more recent sdk compiling. I'm no longer able to apply the above to a field that is hidden. Seems you must have your field visible and larger than 0 now for keyboard to appear. I was doing this because my app is more of a game using the keyboard as entry against an image. So all I had to do was change:

<EditText
        android:id="@+id/kb_input"
        android:layout_width="0dp"
        android:layout_height="0dp"
      />

to

<EditText
        android:id="@+id/kb_input"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@color/black"
        android:textColorHighlight="@color/black"
        android:backgroundTint="@color/black"
        android:cursorVisible="false"
      />

My background was black so while the EditText is now visible it looks invisible on the black background.

Nations answered 10/2, 2021 at 20:12 Comment(1)
I was struggling with this problem for a while now, this solved it!Lustrum
R
0

This works for me:

public void requestFocusAndShowSoftInput(View view){
    view.requestFocus();
    InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
    inputMethodManager.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
}
Rumania answered 30/3, 2018 at 22:22 Comment(0)
S
0

If you're trying to show the soft keyboard in a Fragment, you need to wait until the Activity has been created before calling showSoftInput(). Sample code:

public class SampleFragment extends Fragment {

    private InputMethodManager mImm;
    private TextView mTextView;

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        mImm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        showSoftKeyboard(mTextView);
    }

    /**
     * Request the InputMethodManager show the soft keyboard.  Call this in {@link #onActivityCreated(Bundle)}.
     * @param view the View which would like to receive text input from the soft keyboard
     */
    public void showSoftKeyboard(View view) {
        if (view.requestFocus()) {
            mImm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
        }
    }

}
Scincoid answered 4/6, 2019 at 21:44 Comment(0)
C
0

Removing android:windowSoftInputMode from the manifest solved my problem!

Curtice answered 7/7, 2021 at 14:28 Comment(0)
B
0

in my case, i solved this problem putting this code in onResume simply:

    override fun onResume() {
        super.onResume()
        binding.edittext.requestFocus()
        val imm = 
            requireContext().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        imm.showSoftInput(binding.edittext, InputMethodManager.SHOW_IMPLICIT)
    }
Blast answered 31/1, 2023 at 9:1 Comment(0)
B
0

@Zar E Ahmer

solution works perfectly.
if still anybody has problem,
increase delay time "100" at the bottom of code to 300 or something;

InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
editText.postDelayed(new Runnable()
{
    @Override
    public void run()
    {
        editText.requestFocus();
        imm.showSoftInput(editText, 0);
    }
}, 100);//increase this time to 300 or something;
Backman answered 21/8, 2023 at 16:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.