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.
Related
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
}
}
I have a request from a client which says something like this: after a user inserts his name, on tap out validate with server.
I never heard about tapping out from a field in Android yet. (tap out means when you are writing something into an EditText, then you click on other view, hide keyboard and call focus change listener).
Do you have any idea about this implemented in Android? Thanks.
Update, after marked duplicated: I already did my research for this a lot, this is why I asked here for an opinion.
The above case is just an example. My main interest is regarding tapping out from EditText (TAP on another view with NO action - e.g. a TextView with no clickable function). I hope it's clear now.
You can force Android to hide the virtual keyboard using the InputMethodManager, calling hideSoftInputFromWindow, passing in the token of the window containing your focused view.
InputMethodManager methodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
if (methodManager != null) {
methodManager.hideSoftInputFromWindow(mEditText.getWindowToken(),0);
}
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
I want to show Google Voice Typing IME on my EditText by clicking on Button. So, according to this article and source code I should write this code
inputMethodManager.setInputMethodAndSubtype(IBinder token, String id, InputMethodSubtype subtype)
The problem is: where to find appropriate token. In the source code I saw this
mInputMethodService.getWindow().getWindow().getAttributes().token
It works great, but this code located in InputMetodService superclass, so it has access to InputMethodService instance. But i don't (unfortunately :) ).
Please tell me if you have any suggestions. Thanks.
NOT WORKS: EditText.getWindowToken()
Due to security reasons android doesn't allows application to change the inputMethod type. The article you mentioned is for integrating the google IME in custom implemented IME, it is not applicable for applications.
you can check documentation of InputMethodManager here
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.
you can prompt the user to switch to new IME in your onClick Callback like this:
InputMethodManager imm = (InputMethodManager)
getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showInputMethodPicker();
I want to detect "user inactivity" in my Android app. To be more precise: I want to detect if the user has NOT done any interaction with my app (touching the screen, scrolling, input texts ...) for a specific time. Technically I use a timer that is reseted on each (user) interaction.
In my activity, I override the onUserInteraction method to detect interactions like scrolling, touching the screen ...
#Override
public void onUserInteraction(){
resetInactiveTimer();
}
Unfortunately, onUserInteraction is not called when the user interacts with the soft keyboard. I think the reason is, that the soft keyboard is not part of my Activity.
For the edit texts in my app I use TextWatcher and the onTextChanged method which works fine. But my app also contain a WebView that loads arbitrary web pages. Of course some web pages could contain input fields and I do not know how to detect that the user interacts with the soft keyboard to edit those text fields.
Still interested in this?
Your activity implements KeyEvent.Callback, so you can override onKeyDown:
#Override
public boolean onKeyDown (int keyCode, KeyEvent event) {
resetInactiveTimer();
return false;
}
Alternatively, (in the most common circumstance) if the key is pressed with the cursor in an EditText or similar, you will need implement an OnKeyListener and use the onKey method to call resetInactiveTimer();