Buckets:
NaTo1000/termux-app-bucket / termux-shared /src /main /java /com /termux /shared /view /KeyboardUtils.java
| package com.termux.shared.view; | |
| import android.app.Activity; | |
| import android.content.Context; | |
| import android.content.res.Configuration; | |
| import android.inputmethodservice.InputMethodService; | |
| import android.os.Build; | |
| import android.view.View; | |
| import android.view.WindowInsets; | |
| import android.view.WindowManager; | |
| import android.view.inputmethod.InputMethodManager; | |
| import androidx.annotation.NonNull; | |
| import androidx.annotation.RequiresApi; | |
| import androidx.core.view.WindowInsetsCompat; | |
| import com.termux.shared.logger.Logger; | |
| public class KeyboardUtils { | |
| private static final String LOG_TAG = "KeyboardUtils"; | |
| public static void setSoftKeyboardVisibility( final Runnable showSoftKeyboardRunnable, final Activity activity, final View view, final boolean visible) { | |
| if (visible) { | |
| // A Runnable with a delay is used, otherwise soft keyboard may not automatically open | |
| // on some devices, but still may fail | |
| view.postDelayed(showSoftKeyboardRunnable, 500); | |
| } else { | |
| view.removeCallbacks(showSoftKeyboardRunnable); | |
| hideSoftKeyboard(activity, view); | |
| } | |
| } | |
| /** | |
| * Toggle the soft keyboard. The {@link InputMethodManager#SHOW_FORCED} is passed as | |
| * {@code showFlags} so that keyboard is forcefully shown if it needs to be enabled. | |
| * | |
| * This is also important for soft keyboard to be shown when a hardware keyboard is connected, and | |
| * user has disabled the {@code Show on-screen keyboard while hardware keyboard is connected} toggle | |
| * in Android "Language and Input" settings but the current soft keyboard app overrides the | |
| * default implementation of {@link InputMethodService#onEvaluateInputViewShown()} and returns | |
| * {@code true}. | |
| */ | |
| public static void toggleSoftKeyboard(final Context context) { | |
| if (context == null) return; | |
| InputMethodManager inputMethodManager = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); | |
| if (inputMethodManager != null) | |
| inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); | |
| } | |
| /** | |
| * Show the soft keyboard. The {@code 0} value is passed as {@code flags} so that keyboard is | |
| * forcefully shown. | |
| * | |
| * This is also important for soft keyboard to be shown on app startup when a hardware keyboard | |
| * is connected, and user has disabled the {@code Show on-screen keyboard while hardware keyboard | |
| * is connected} toggle in Android "Language and Input" settings but the current soft keyboard app | |
| * overrides the default implementation of {@link InputMethodService#onEvaluateInputViewShown()} | |
| * and returns {@code true}. | |
| * https://cs.android.com/android/platform/superproject/+/android-11.0.0_r3:frameworks/base/core/java/android/inputmethodservice/InputMethodService.java;l=1751 | |
| * | |
| * Also check {@link InputMethodService#onShowInputRequested(int, boolean)} which must return | |
| * {@code true}, which can be done by failing its {@code ((flags&InputMethod.SHOW_EXPLICIT) == 0)} | |
| * check by passing {@code 0} as {@code flags}. | |
| * https://cs.android.com/android/platform/superproject/+/android-11.0.0_r3:frameworks/base/core/java/android/inputmethodservice/InputMethodService.java;l=2022 | |
| */ | |
| public static void showSoftKeyboard(final Context context, final View view) { | |
| if (context == null || view == null) return; | |
| InputMethodManager inputMethodManager = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); | |
| if (inputMethodManager != null) | |
| inputMethodManager.showSoftInput(view, 0); | |
| } | |
| public static void hideSoftKeyboard(final Context context, final View view) { | |
| if (context == null || view == null) return; | |
| InputMethodManager inputMethodManager = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); | |
| if (inputMethodManager != null) | |
| inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0); | |
| } | |
| public static void disableSoftKeyboard(final Activity activity, final View view) { | |
| if (activity == null || view == null) return; | |
| hideSoftKeyboard(activity, view); | |
| setDisableSoftKeyboardFlags(activity); | |
| } | |
| public static void setDisableSoftKeyboardFlags(final Activity activity) { | |
| if (activity != null && activity.getWindow() != null) | |
| activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM, WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); | |
| } | |
| public static void clearDisableSoftKeyboardFlags(final Activity activity) { | |
| if (activity != null && activity.getWindow() != null) | |
| activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); | |
| } | |
| public static boolean areDisableSoftKeyboardFlagsSet(final Activity activity) { | |
| if (activity == null || activity.getWindow() == null) return false; | |
| return (activity.getWindow().getAttributes().flags & WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM) != 0; | |
| } | |
| public static void setSoftKeyboardAlwaysHiddenFlags(final Activity activity) { | |
| if (activity != null && activity.getWindow() != null) | |
| activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); | |
| } | |
| public static void setSoftInputModeAdjustResize(final Activity activity) { | |
| // TODO: The flag is deprecated for API 30 and WindowInset API should be used | |
| // https://developer.android.com/reference/android/view/WindowManager.LayoutParams#SOFT_INPUT_ADJUST_RESIZE | |
| // https://medium.com/androiddevelopers/animating-your-keyboard-fb776a8fb66d | |
| // https://stackoverflow.com/a/65194077/14686958 | |
| if (activity != null && activity.getWindow() != null) | |
| activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); | |
| } | |
| /** | |
| * Check if soft keyboard is visible. | |
| * Does not work on android 7 but does on android 11 avd. | |
| * | |
| * @param activity The Activity of the root view for which the visibility should be checked. | |
| * @return Returns {@code true} if soft keyboard is visible, otherwise {@code false}. | |
| */ | |
| public static boolean isSoftKeyboardVisible(final Activity activity) { | |
| if (activity != null && activity.getWindow() != null) { | |
| WindowInsets insets = activity.getWindow().getDecorView().getRootWindowInsets(); | |
| if (insets != null) { | |
| WindowInsetsCompat insetsCompat = WindowInsetsCompat.toWindowInsetsCompat(insets); | |
| if (insetsCompat.isVisible(WindowInsetsCompat.Type.ime())) { | |
| Logger.logVerbose(LOG_TAG, "Soft keyboard visible"); | |
| return true; | |
| } | |
| } | |
| } | |
| Logger.logVerbose(LOG_TAG, "Soft keyboard not visible"); | |
| return false; | |
| } | |
| /** | |
| * Check if hardware keyboard is connected. | |
| * Based on default implementation of {@link InputMethodService#onEvaluateInputViewShown()}. | |
| * | |
| * https://developer.android.com/guide/topics/resources/providing-resources#ImeQualifier | |
| * | |
| * @param context The Context for operations. | |
| * @return Returns {@code true} if device has hardware keys for text input or an external hardware | |
| * keyboard is connected, otherwise {@code false}. | |
| */ | |
| public static boolean isHardKeyboardConnected(final Context context) { | |
| if (context == null) return false; | |
| Configuration config = context.getResources().getConfiguration(); | |
| return config.keyboard != Configuration.KEYBOARD_NOKEYS | |
| || config.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO; | |
| } | |
| /** | |
| * Check if soft keyboard should be disabled based on user configuration. | |
| * | |
| * @param context The Context for operations. | |
| * @return Returns {@code true} if device has soft keyboard should be disabled, otherwise {@code false}. | |
| */ | |
| public static boolean shouldSoftKeyboardBeDisabled(final Context context, final boolean isSoftKeyboardEnabled, final boolean isSoftKeyboardEnabledOnlyIfNoHardware) { | |
| // If soft keyboard is disabled by user regardless of hardware keyboard | |
| if (!isSoftKeyboardEnabled) { | |
| return true; | |
| } else { | |
| /* | |
| * Currently, for this case, soft keyboard will be disabled on Termux app startup and | |
| * when switching back from another app. Soft keyboard can be temporarily enabled in | |
| * show/hide soft keyboard toggle behaviour with keyboard toggle buttons and will continue | |
| * to work when tapping on terminal view for opening and back button for closing, until | |
| * Termux app is switched to another app. After returning back, keyboard will be disabled | |
| * until toggle is pressed again. | |
| * This may also be helpful for the Lineage OS bug where if "Show soft keyboard" toggle | |
| * in "Language and Input" is disabled and Termux is started without a hardware keyboard | |
| * in landscape mode, and then the keyboard is connected and phone is rotated to portrait | |
| * mode and then keyboard is toggled with Termux keyboard toggle buttons, then a blank | |
| * space is shown in-place of the soft keyboard. Its likely related to | |
| * WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE which pushes up the view when | |
| * keyboard is opened instead of the keyboard opening on top of the view (hiding stuff). | |
| * If the "Show soft keyboard" toggle was disabled, then this resizing shouldn't happen. | |
| * But it seems resizing does happen, but keyboard is never opened since its not supposed to. | |
| * https://github.com/termux/termux-app/issues/1995#issuecomment-837080079 | |
| */ | |
| // If soft keyboard is disabled by user only if hardware keyboard is connected | |
| if(isSoftKeyboardEnabledOnlyIfNoHardware) { | |
| boolean isHardKeyboardConnected = KeyboardUtils.isHardKeyboardConnected(context); | |
| Logger.logVerbose(LOG_TAG, "Hardware keyboard connected=" + isHardKeyboardConnected); | |
| return isHardKeyboardConnected; | |
| } else { | |
| return false; | |
| } | |
| } | |
| } | |
| } | |
Xet Storage Details
- Size:
- 10.5 kB
- Xet hash:
- 10348cbaca5c47c06ec902a836e49123a6dd06f3e58f3959f173a10a7e7e553a
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.