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


当前回答

@iWantScala的回答很棒,但不适合我 rootView.getRootView().getHeight()总是有相同的值

一种方法是定义两个变量

private int maxRootViewHeight = 0;
private int currentRootViewHeight = 0;

添加全局监听器

rootView.getViewTreeObserver()
    .addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            currentRootViewHeight = rootView.getHeight();
            if (currentRootViewHeight > maxRootViewHeight) {
                maxRootViewHeight = currentRootViewHeight;
            }
        }
    });

然后检查

if (currentRootViewHeight >= maxRootViewHeight) {
    // Keyboard is hidden
} else {
    // Keyboard is shown
}

工作正常

其他回答

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

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

如果你的应用程序支持AndroidR的api,那么你可以使用下面的方法。

In kotlin :
    var imeInsets = view.rootWindowInsets.getInsets(Type.ime()) 
    if (imeInsets.isVisible) { 
        view.translationX = imeInsets.bottom 
    }

注意:这只适用于AndroidR和以下的android版本需要遵循一些其他的答案,否则我会更新它。

非常容易

1. 把id放在根视图上

rootView只是一个视图指向我的根视图在这种情况下,一个相对布局:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:id="@+id/addresses_confirm_root_view"
                android:background="@color/WHITE_CLR">

2. 在Activity中初始化根视图:

RelativeLayout rootView = (RelativeLayout) findViewById(R.id.addresses_confirm_root_view);

3.使用getViewTreeObserver()检测键盘是否打开或关闭

    rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                int heightDiff = rootView.getRootView().getHeight() - rootView.getHeight();
                
                if (heightDiff > 100) { // Value should be less than keyboard's height 
                    Log.e("MyActivity", "keyboard opened");
                } else { 
                    Log.e("MyActivity", "keyboard closed");
                }
            }
        });

我通过设置一个GlobalLayoutListener来做到这一点,如下所示:

final View activityRootView = findViewById(R.id.activityRoot);
activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(
        new OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                int heightView = activityRootView.getHeight();
                int widthView = activityRootView.getWidth();
                if (1.0 * widthView / heightView > 3) {
                    //Make changes for Keyboard not visible
                } else {
                    //Make changes for keyboard visible
                }
            }
        });