Search code examples
pythonandroidkivy

Hide default android keyboard


I have a simple kivy app and I can't hide default android keyboard. I'm try to use android.hide_keyboard() but it don't work in my device. The most interesting thing is that this function works for Pydroid, but on the emulator and on the device the app immediately breaks without python errors. My TextInput code:

class MyTextInput(TextInput):

    def __init__(self, **kwargs):
        super(MyTextInput, self).__init__(**kwargs)
        self.wx = self.x
        self.wy = self.y
        self.wpos = self.pos
        self._keyboard_mode = 'dock'
        self.allow_vkeyboard = True
        self.single_vkeyboard = True

    def on_focus(self, instance, value, *largs):
        if platform == 'android':
            import android
            android.hide_keyboard()
        win = self.get_root_window()
        if win:
            win.release_all_keyboards()
            win._keyboards = {}
            win.set_vkeyboard_class(MyKeyboard)

Solution

  • After a long time trying to figure out android.hide_keyboard() function decided to use its own JAVA function.

    public class KeyboardUtils {
    
        public static void hideKeyboard(Activity activity) {
            InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
                imm.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
        }
    }
    

    The file of the same name was placed in the java root of the build folder (for me it is ...src/main/java/org/jnius).

    And the code of the MyTextInput class:

    class MyTextInput(TextInput):
    
        def __init__(self, **kwargs):
            super(MyTextInput, self).__init__(**kwargs)
            self.wx = self.x
            self.wy = self.y
            self.wpos = self.pos
            self.keyboard_mode = 'managed'
            self.allow_vkeyboard = True
            self.single_vkeyboard = True
            self.visible = False
    
        def on_touch_down(self, touch):
            changed = False
            win = self.get_root_window()
            if win:
                win.release_all_keyboards()
                win._keyboards = {}
                win.set_vkeyboard_class(MyKeyboard)
            if self.pos[0] <= touch.pos[0] <= self.pos[0] + self.width:
                if self.pos[1] <= touch.pos[1] <= self.pos[1] + self.height:
                    if not self.visible:
                        self.show_keyboard()
                        if platform == 'android':
                            from jnius import autoclass, cast
                            utils = autoclass('org.jnius.KeyboardUtils')
                            activity = autoclass('org.kivy.android.PythonActivity')
                            current_activity = cast('android.app.Activity',
                                                    activity.mActivity)
                            utils.hideKeyboard(current_activity)
                        self.visible = True
                        changed = True
                        self.focus = True
    
            if not changed:
                if self.visible:
                    self.hide_keyboard()
                    self.visible = False