Android系统中是否有一种方法可以检测软件(也就是Android。“软”)键盘在屏幕上可见吗?


当前回答

这里有一个工作区,以了解软键盘是否可见。

使用ActivityManager.getRunningServices(max_count_of_services)检查系统上正在运行的服务; 从返回的ActivityManager。运行ningserviceinfo实例,检查软键盘服务的clientCount值。 前面提到的clientCount将在每次显示软键盘时递增。例如,如果clientCount最初是1,那么在显示键盘时它将是2。 在键盘撤销时,clientCount递减。在本例中,它重置为1。

一些流行的键盘在它们的classname中有特定的关键字:

谷歌AOSP = IME Swype =输入法 Swiftkey = KeyboardService Fleksy =键盘 Adaptxt = IME (KPTAdaptxtIME) 智能=键盘(SmartKeyboard)

从ActivityManager。RunningServiceInfo,在ClassNames中检查上述模式。 同时,ActivityManager。RunningServiceInfo的clientPackage=android,表示键盘绑定到系统。

可以将上述信息进行严格的组合,以判断软键盘是否可见。

其他回答

在Android中,你可以通过ADB shell进行检测。我写下并使用了这个方法:

{
        JSch jsch = new JSch();
        try {
            Session session = jsch.getSession("<userName>", "<IP>", 22);
            session.setPassword("<Password>");
            Properties config = new Properties();
            config.put("StrictHostKeyChecking", "no");
            session.setConfig(config);
            session.connect();

            ChannelExec channel = (ChannelExec)session.openChannel("exec");
            BufferedReader in = new BufferedReader(new    
            InputStreamReader(channel.getInputStream()));
            channel.setCommand("C:/Android/android-sdk/platform-tools/adb shell dumpsys window 
            InputMethod | findstr \"mHasSurface\"");
            channel.connect();

            String msg = null;
            String msg2 = " mHasSurface=true";

            while ((msg = in.readLine()) != null) {
                Boolean isContain = msg.contains(msg2);
                log.info(isContain);
                if (isContain){
                    log.info("Hiding keyboard...");
                    driver.hideKeyboard();
                }
                else {
                    log.info("No need to hide keyboard.");
                }
            }

            channel.disconnect();
            session.disconnect();

        } catch (JSchException | IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }
}

现在终于可以直接从基于Kotlin的Android R开始了。

 val imeInsets = requireView().rootWindowInsets.isVisible(WindowsInsetsCompat.Type.ime()) 
    if (imeInsets) { 
     //Ime is visible
     //Lets move our view by the height of the IME
     view.translationX = imeInsets.bottom }

我是这样做的,但只有当你的目标是关闭/打开键盘时,它才有意义。

关闭示例:(检查键盘是否已经关闭,如果没有关闭)

imm.showSoftInput(etSearch, InputMethodManager.HIDE_IMPLICIT_ONLY, new ResultReceiver(null) {
                    @Override
                    protected void onReceiveResult(int resultCode, Bundle resultData) {
                        super.onReceiveResult(resultCode, resultData);
                        if (resultCode != InputMethodManager.RESULT_UNCHANGED_HIDDEN)
                            imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
                    }
                });

如你所知,android软件的键盘只有在有可能的输入事件时才可见。换句话说,只有当EditText被聚焦时,键盘才可见。这意味着你可以通过使用OnFocusChangeListener获得键盘是否可见。

//Declare this Globally

public boolean isKeyBoardVisible = false;

//In OnCreate *[For Activity]*, OnCreateView *[For Fragment]*

text_send.setOnFocusChangeListener(new View.OnFocusChangeListener() {

    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if(hasFocus)
            isKeyBoardVisible = true;
        else
            isKeyBoardVisible = false;
    }
});

现在你可以在类的任何地方使用isKeyBoardVisible变量来获取键盘是否打开。这对我来说很有效。

注意:当使用InputMethodManager以编程方式打开键盘时,这个过程不起作用,因为它不调用OnFocusChangeListener。

谢谢大家的回答,我是根据自己的情况想出来的

/**
 * Add global layout listener to observe system keyboard visibility
 */
private void initObserverForSystemKeyboardVisibility() {
    getRootView().getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            //Add your own code here
            Log.d("TEST_CODE", "isSystemKeyboardVisible:" + isSystemKeyboardVisible())
        }
    });
}


/**
 * Check system keyboard visibility
 * @return true if visible
 */
public boolean isSystemKeyboardVisible() {
    try {
        final InputMethodManager manager = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
        final Method windowHeightMethod = InputMethodManager.class.getMethod("getInputMethodWindowVisibleHeight");
        final int height = (int) windowHeightMethod.invoke(manager);
        return height > 0;
    } catch (Exception e) {
        return false;
    }
}