How to disable softKeyboard if there is a hardware Keyboard - android

Actually i'm checking by this method if there is a hardware keyboard on my device
private boolean isHardwareKeyboardAvailable() { return getResources().getConfiguration().keyboard != Configuration.KEYBOARD_NOKEYS; }
But now i would be able to disable the softKeyboard for that activity if the result of that boolean is true. How can i do?
Actually for a target of devices i set in my manifest
android:windowSoftInputMode="stateVisible"
But i have to disable even it.
Any suggestion?

The easiest way to do it is by preventing the keyboard from popping up automatically:
this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
Put this code when you realized that the phone has physical keyboard.

Related

How to prevent back button from dismissing the keyboard in flutter?

I want to set the keyboard to be always opened in the chat page and should not be dismissable by the back button.
The WillPopScope() widget is only preventing the back button from navigating back to the previous page however is still dismissing the keyboard. I am getting the keyboard opened initially via by setting autofocus = true in the textformfield so the only issue I am facing is on preventing the dismissal of the keyboard.
I have looked upon multiple questions in Stack however could not find a suitable solution to this issue. I have been searching for the answer for over 2 months now and hope someone is able to assist me with this issue.
UPDATE:
I did the following change to my heightofdevice where I subtracted the MediaQuery.of(context).viewInsets.bottom and now the transition of the keyboard is better.
I realised the previous method of me trying to fix the keyboard and preventing it from being dismissed had too many fixes to be done on a native level using Java or Kotlin for Android. I initially wanted to fix the keyboard as the transition was poor but with the following method, the transition is better now but there are still room for improvement.
var heightStatusBar = MediaQuery.of(context).padding.top;
var bottom = MediaQuery.of(context).viewInsets.bottom;
widthofdevice = MediaQuery.of(context).size.width;
heightofdevice =(MediaQuery.of(context).size.height) -
heightStatusBar - bottom;
The problem is that when the keyboard is opened and the user press the Android Backbutton, the app doesn't change the proper Focus of the keyboard, that is, even if it closes the keyboard, the focus continue as True...
With this, the next tap on the textfield to open again the keyboard, the focus is true and the flutter retrieve the information that it already is open and doesn't do anything.
To fix this, you can wrap your tap of the TextField using a GestureDetector and use a combine Focus and viewInsets validation.
void _onFocus() {
if (_focusNode.hasFocus && MediaQuery.of(context).viewInsets.bottom == 0) {
_focusNode.unfocus();
Future.delayed(const Duration(microseconds: 1),
() => _focusNode.requestFocus());
} else {
_focusNode.requestFocus();
}
}
With this, if the user press the backbitten to close the keyboard and press on the TextField to open again, this validation will fail in MediaQuery.viewInsets and it will update the real status of Focus.

How to know when the user is done with text entry on an EditText control?

I want to be able to know when a user is done entering text in an EditText control. I'm thinking maybe it's best to know when the keyboard is closed or something similar. This is using Kotlin on Android app. I'm not sure why it's so hard to find basic answers like this. Maybe I'm searching with the wrong question (new to Android dev).
Using keyboard close as an indicator that the user finished entering text is a bad idea (the user might open the keyboard again to enter more text). A better solution would be to explicitly require for the user to indicate that he has finished entering the data.
You could use a "submit" button.
You can also set the android:imeOptions of EditText to actionDone and set a listener on the EditText.
editText.setOnEditorActionListener(new EditText.OnEditorActionListener() {
#Override
public boolean onEditorAction(EditText v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE) {
//do your stuff
return true;
}
return false;
}
});
Update - Assuming keyboard close as the indicator is bad for a couple of reasons,
There is no 'proper' way to monitor the soft keyboard. You could try listening to the focus of the EditText or you could use the height difference to guesstimate whether the soft keyboard is open or closed(the option used in most keyboard listener libraries). But these aren't reliable and might break in production.
It's an 'unexpected' application behavior for the user. For example, the keyboard can be removed by pressing the back button. In general, the user would expect that the action would not proceed if the back button is pressed. But if you listen to keyboard close, then it would end up resulting in poorer UX.
There are no actual reasons why you would want to use keyboard close as the trigger. If you want to perform the action as the user types, then you should use TextWatcher, otherwise stick to explicit confirm options.
use onFocusChangeListener to know if the user has finished to add text and has leave the textInput focus.
Example
editText?.onFocusChangeListener =
View.OnFocusChangeListener { _,
hasFocus ->
if (!hasFocus) {
// code to execute when EditText loses focus
}
}

Samsung Keyboard Suppress

With a bluetooth keyboard connected, the Note 2 forces the switch back to the Samsung keyboard. This is a problem, as the Samsung keyboard always pops up when I'm trying to type with my external, taking up screen space and defeating half the purpose. I could write an app that forces the switch back, probably, but I'd still have to hit Enter/OK everytime the keyboard connects. I disabled the Samsung keyboard altogether, but the OK button still shows up. Is there some sort of service that does this or something? Because if I can't block/disable whatever it is, it's going to mess with my workflow, seeing as I bought this K810 to switch between multiple devices.
Here's a code snippet I use in order to prevent the keyboard to popup at application start:
public void hideSoftKeyboard(View v) {
Activity activity = (Activity) v.getContext();
InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
}
I think that if you can detenct the event with:
http://developer.android.com/reference/android/content/res/Configuration.html#keyboard
There are some flags, which indicate what's the inserted keyboard.
Or just try this one, even though i didn't test it:
public boolean onEvaluateInputViewShown() {
return false;
}
Let me know then of the results.
Thanks

Using subclass of Input Method Service

I extended InputMethodService hoping to use this Service for showing a soft keyboard even though a hard keyboard is connected(based off the following post Show soft keyboard even though a hardware keyboard is connected). Is there a way to bind to this service within the app without having to declare it in the manifest? The end result is to have InputMethodService.onEvaluateInputViewShown return true so that the soft keyboard will show even though a hard keyboard is connected.
I would like to use the extended class MultiInputMethodService with the inputmethodmanager in show/hideSoftKeyboard:
public class MultiInputMethodService extends InputMethodService {
#Override
public boolean onEvaluateInputViewShown () {
Log.i("onEvaluateInputViewShow","onEvaluateInputViewShown");
return true;
}
}
my activity:
private void showSoftKeyboard() {
InputMethodManager imm = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,InputMethodManager.HIDE_IMPLICIT_ONLY );
}
private void hideSoftKeyboard() {
InputMethodManager imm = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(this.myInput.getEditText().getWindowToken(), 0);
}
The IMS framework really needs to be used as a whole. If you want to be the keyboard, the user will need to select you as the default keyboard via settings. If you were to try to bind with the service directly I'm not sure what the result would be, but my guess would be that it ends badly. By having the user set you as the default keyboard, you will automatically be used as the keyboard in all apps.
Of course, you can't just set that yourself, for security purposes. Otherwise keyboards would be fighting over the setting. The user has to set it manually.
EDIT:
I found the documentation you are referring to(under the "Security Section"):
http://developer.android.com/reference/android/view/inputmethod/InputMethodManager.html
A client application can ask that the system let the user pick a new
IME, but can not programmatically switch to one itself. This avoids
malicious applications from switching the user to their own IME, which
remains running when the user navigates away to another application.
An IME, on the other hand, is allowed to programmatically switch the
system to another IME, since it already has full control of user
input.
The user must explicitly enable a new IME in settings before they can
switch to it, to confirm with the system that they know about it and
want to make it available for use.

Replicate physical keyboard on the Android emulator

I have a couple of reports on my recent app of a bug related to a phone with a physical keyboard, an EditText, and an orientation change.
I don’t have a phone with a physical keyboard, so I have to try to replicate the problem somehow. In the emulator creation screen under the AVD manager in Eclipse, there is an option for “keyboard support.” Is this how I would replicate a physical keyboard phone on the emulator?
Are there any other ways I could debug my problem? Thanks.
Edit upon request: Current symptoms as communicated by the user are
EditText Preference not getting saved (I'm making this assumption based on their input)
Something to due with the activity not switching orientation properly when the user opens up the keypad. It requires the user to open it twice.
Complete Activity code. NOTE: The EditText below is not the problem EditText.
public class GreetingOptions extends PreferenceActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.layout.greeting_options);
//Set the edit text preference to only accept positive integers
EditTextPreference fontSize = (EditTextPreference) findPreference("fontSize");
EditText myEditText = (EditText) fontSize.getEditText();
myEditText.setKeyListener(DigitsKeyListener.getInstance(false, false));
}
}
When a user slides out a physical keyboard your app is destroyed and recreated, just the same as what happens when the orientation changes. I would suggest attempting to replicate the problem using an orientation change. You can accomplish this in the emulator using:
Switch to previous layout orientation (for example, portrait, landscape) KEYPAD_7, Ctrl-F11
Switch to next layout orientation (for example, portrait, landscape) KEYPAD_9, Ctrl-F12
To fix the issue I suspect you will need to save the state of your Activity when your app is destroyed and restore it when it is recreated. You may find it useful to review the application lifecycle.
Application fundamentals
Android emulator
This isn't really an answer, but my experience with the emulator is that its support for any 'physical' inputs is limited to none. Even trying to simulate having a headset plugged in was more than it could handle.
I'd suggest you try to beg, borrow or steal a real phone with a keyboard, and install the app on that.
Sorry I can't be more help :(

Categories

Resources