Android show softkeyboard with showSoftInput is not working?

后端 未结 12 1989
抹茶落季
抹茶落季 2020-12-28 13:49

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 doe

相关标签:
12条回答
  • 2020-12-28 14:00

    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.

    0 讨论(0)
  • 2020-12-28 14:05

    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://stackoverflow.com/a/16882749/5903344

    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.

    0 讨论(0)
  • 2020-12-28 14:10

    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());
    
    0 讨论(0)
  • 2020-12-28 14:11

    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);
            }
    
    0 讨论(0)
  • 2020-12-28 14:13

    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

    0 讨论(0)
  • 2020-12-28 14:13

    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.

    0 讨论(0)
提交回复
热议问题