监听软键盘状态、高度
import android.app.Activity;
import android.content.res.Resources;
import android.graphics.Rect;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.widget.FrameLayout;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
/**
 * Title:
 * Describe:
 * Remark:
 * <p>
 * Created by Milo
 * E-Mail : 303767416@qq.com
 * 2024/3/25
 */
public final class KeyboardUtils {
    public static int sDecorViewInvisibleHeightPre;
    private static ViewTreeObserver.OnGlobalLayoutListener onGlobalLayoutListener;
    private static int mNavHeight;
    public static int sDecorViewDelta = 0;
    public interface NavigationBarCallback {
        void onHeight(int height, boolean hasNavigationBar);
    }
    public interface KeyboardHeightListener {
        void onKeyboardHeightChanged(int height);
    }
    private static int getDecorViewInvisibleHeight(final Activity activity) {
        final View decorView = activity.getWindow().getDecorView();
        if (decorView == null) return sDecorViewInvisibleHeightPre;
        final Rect outRect = new Rect();
        decorView.getWindowVisibleDisplayFrame(outRect);
        int delta = Math.abs(decorView.getBottom() - outRect.bottom);
        if (delta <= mNavHeight) {
            sDecorViewDelta = delta;
            return 0;
        }
        return delta - sDecorViewDelta;
    }
    public static void registerKeyboardHeightListener(final Activity activity, final KeyboardHeightListener listener) {
        final int flags = activity.getWindow().getAttributes().flags;
        if ((flags & WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS) != 0) {
            activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
        }
        final FrameLayout contentView = activity.findViewById(android.R.id.content);
        sDecorViewInvisibleHeightPre = getDecorViewInvisibleHeight(activity);
        onGlobalLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                int height = getDecorViewInvisibleHeight(activity);
                if (sDecorViewInvisibleHeightPre != height) {
                    listener.onKeyboardHeightChanged(height);
                    sDecorViewInvisibleHeightPre = height;
                }
            }
        };
        //获取到导航栏高度之后再添加布局监听
        getNavigationBarHeight(activity, new NavigationBarCallback() {
            @Override
            public void onHeight(int height, boolean hasNav) {
                mNavHeight = height;
                contentView.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayoutListener);
            }
        });
    }
    public static void unregisterKeyboardHeightListener(Activity activity) {
        onGlobalLayoutListener = null;
        View contentView = activity.getWindow().getDecorView().findViewById(android.R.id.content);
        if (contentView == null) return;
        contentView.getViewTreeObserver().removeGlobalOnLayoutListener(onGlobalLayoutListener);
    }
    private static int getNavBarHeight() {
        Resources res = Resources.getSystem();
        int resourceId = res.getIdentifier("navigation_bar_height", "dimen", "android");
        if (resourceId != 0) {
            return res.getDimensionPixelSize(resourceId);
        } else {
            return 0;
        }
    }
    public static void getNavigationBarHeight(Activity activity, NavigationBarCallback callback) {
        View view = activity.getWindow().getDecorView();
        boolean attachedToWindow = view.isAttachedToWindow();
        if (attachedToWindow) {
            WindowInsetsCompat windowInsets = ViewCompat.getRootWindowInsets(view);
            assert windowInsets != null;
            int height = windowInsets.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom;
            boolean hasNavigationBar = windowInsets.isVisible(WindowInsetsCompat.Type.navigationBars()) &&
                    windowInsets.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom > 0;
            if (height > 0) {
                callback.onHeight(height, hasNavigationBar);
            } else {
                callback.onHeight(getNavBarHeight(), hasNavigationBar);
            }
        } else {
            view.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
                @Override
                public void onViewAttachedToWindow(View v) {
                    WindowInsetsCompat windowInsets = ViewCompat.getRootWindowInsets(v);
                    assert windowInsets != null;
                    int height = windowInsets.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom;
                    boolean hasNavigationBar = windowInsets.isVisible(WindowInsetsCompat.Type.navigationBars()) &&
                            windowInsets.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom > 0;
                    if (height > 0) {
                        callback.onHeight(height, hasNavigationBar);
                    } else {
                        callback.onHeight(getNavBarHeight(), hasNavigationBar);
                    }
                }
                @Override
                public void onViewDetachedFromWindow(View v) {
                }
            });
        }
    }
}
显示软键盘
        <activity
            android:name=".ui.chat.CustomScenesActivity"
            android:screenOrientation="portrait"
            android:windowSoftInputMode="stateVisible"/>
mBinding.etInput.setFocusable(true);
mBinding.etInput.setFocusableInTouchMode(true);
mBinding.etInput.requestFocus();
    private void showKeyboard() {
        try {
            InputMethodManager manager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
            if (manager != null && manager.isActive() && getCurrentFocus() != null) {
                manager.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }