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


当前回答

A可能会使用:

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

    Log.d(
    getClass().getSimpleName(), 
    String.format("conf: %s", newConfig));

    if (newConfig.hardKeyboardHidden != hardKeyboardHidden) {
        onHardwareKeyboardChange(newConfig.hardKeyboardHidden);

        hardKeyboardHidden = newConfig.hardKeyboardHidden;
    }

    if (newConfig.keyboardHidden != keyboardHidden) {
        onKeyboardChange(newConfig.keyboardHidden);

        keyboardHidden = newConfig.hardKeyboardHidden;
    }

}

public static final int KEYBOARDHIDDEN_UNDEFINED = 0;
public static final int KEYBOARDHIDDEN_NO = 1;
public static final int KEYBOARDHIDDEN_YES = 2;
public static final int KEYBOARDHIDDEN_SOFT = 3;

//todo
private void onKeyboardChange(int keyboardHidden) {

}

//todo
private void onHardwareKeyboardChange(int hardKeyboardHidden) {

}

其他回答

对于我所需要的需求来说,这要简单得多。希望这能有所帮助:

关于MainActivity:

public void dismissKeyboard(){
    InputMethodManager imm =(InputMethodManager)this.getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(mSearchBox.getWindowToken(), 0);
    mKeyboardStatus = false;
}

public void showKeyboard(){
    InputMethodManager imm =(InputMethodManager)this.getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
    mKeyboardStatus = true;
}

private boolean isKeyboardActive(){
    return mKeyboardStatus;
}

mKeyboardStatus的默认基元布尔值将初始化为false。

然后检查如下值,并执行相应的操作:

 mSearchBox.requestFocus();
    if(!isKeyboardActive()){
        showKeyboard();
    }else{
        dismissKeyboard();
    }

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

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

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);
                    }
                });

在我的情况下,我只有一个编辑文本来管理我的布局,所以我想出了这个解决方案。 它工作得很好,基本上它是一个自定义的EditText,它监听焦点,并在焦点改变或按下后退/完成按钮时发送本地广播。 要工作,你需要在你的布局与android: focableintouchmode ="true"和android:focusableInTouchMode="true",因为当你调用clearFocus()的焦点将被重新分配到第一个可聚焦的视图。 虚拟视图示例:

<View
android:layout_width="1dp"
android:layout_height="1dp"
android:focusable="true"
android:focusableInTouchMode="true"/>

额外的信息

检测布局变化差异的解决方案效果不太好,因为它强烈依赖于屏幕密度,因为100px在某些设备上可能很大,而在其他设备上可能没有,你可能会得到误报。 另外,不同的厂商有不同的键盘。

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

/**
 * 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;
    }
}

在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();
        }
    }
}