Why is the soft keyboard being hidden on resume? - android

I have code like the following to immediately show the soft keyboard when entering my app:
#Override
protected void onResume() {
super.onResume();
...
myEditText.requestFocus();
myEditText.postDelayed(new Runnable() {
#Override
public void run() {
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(myEditText, InputMethodManager.SHOW_IMPLICIT);
}
}, 100);
...
}
However, on the Android 2.1 emulator, the keyboard appears and then immediately disappears. If I make the delay longer, like 1000, it reliably appears. On an Android 4.0 emulator, a delay of 100 reliably shows the keyboard, but shorter delays do not.
Does anyone know who might be hiding the keyboard? Is there a reliable way to prevent it? If not, is there a delay I can use to guarantee that the keyboard will show?

If I understand you correctly, I think you can remove the following code in your onResume():
myEditText.postDelayed(new Runnable() {
#Override
public void run() {
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(myEditText, InputMethodManager.SHOW_IMPLICIT);
}
}, 100);
And simply use android:windowSoftInputMode="stateAlwaysVisible" for your Activity in the manifest.

I think what you are seeing is Android identifying the view that should get focus by default and giving it focus (which hides your keyboard). Setting your delay longer or shorter just makes it so your code runs before or after that focus is set. You could figure out what view is getting focus by default, and if you don't want it to ever have focus, set it as focusable false and focusableInTouchMode false. If it does need to have focus at some point, you could set an onFocusChanged listener, and when it gets focus the first time, post your runnable(without delay) to give the focus to the EditText and open the keyboard.

Thanks to #Daniel Smith and #Cookster.
This was happening because I did not set a windowSoftInputMode in my manifest, so it was using the default value (stateUnspecified), which hid the keyboard on startup. Apparently, that setting is applied after some delay on resume, and so my call to show the keyboard only worked if my delay was longer than the built-in delay to hide it.
To fix, I set windowSoftInputMode="stateUnchanged" and then I always either hide or show the keyboard in onResume. I also removed the delay, which was no longer necessary once the built-in hiding was not happening.
Never mind, that mitigated the problem (it lets me reduce the delay), but it didn't fix it completely. There is something very nondeterministic about this, and the keyboard is no longer appearing if I don't use the delay. However, if I reintroduce a delay of about 100ms, the keyboard seems to show up about 90% of the time, which puts me back where I started: why is this happening and what's a safe delay?

put this code in onRun() in onResume() method:
InputMethodManager imm = (InputMethodManager)getSystemService(
Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(myEditText.getWindowToken(), 0);
[Edit]
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
text.requestFocus();
text.postDelayed(new Runnable() {
#Override
public void run() {
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(text, InputMethodManager.SHOW_FORCED);
}
}, 100);
text.postDelayed(new Runnable() {
#Override
public void run() {
InputMethodManager imm = (InputMethodManager)getSystemService(
Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(text.getWindowToken(), 0);
}
}, 200);
}

Related

How to prevent focus on Activity start [duplicate]

This question already has answers here:
How to stop EditText from gaining focus when an activity starts in Android?
(54 answers)
Closed 5 years ago.
I have an Activity with only one EdtiText. When that Activity starts, the EditText is focused and the soft keyboard is shown. This seem to happen after onResume, because when I programmatically hide the keyboard in onResume it doesn't work. When I do this:
#Override
protected void onResume() {
super.onResume();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
InputMethodManager imm = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
//Find the currently focused view, so we can grab the correct window token from it.
//If no view currently has focus, create a new one, just so we can grab a window token from it
imm.hideSoftInputFromWindow(etBarcode.getWindowToken(), 0);
}
}, 500);
}
it hides it (after popping up shortly).
Is there an event on an EditText I can use to preven the keyboard popping up? Or some other way of preventing it to show?
Update focusableInTouchMode does not do what I want, because when set to true the keyboard pops up, when set to false it is not focusable at all.
// Add following code in activity onCreate
this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
For parent layout android:focusableInTouchMode="true"
You can set property of Layout like
android:descendantFocusability="beforeDescendants"
android:focusableInTouchMode="true"
The problem is very complicated, as it's about views getting the focus, and how it's handled by all the layout, about the touch mode being focusable, and last but not least about how the soft keyboard handles that.
But this works for me:
In manifest:
android:windowSoftInputMode="stateHidden|stateAlwaysHidden"
In layout:
android:focusable="true"
android:focusableInTouchMode="true"
and last but not least, touch listener set to the EditText to prevent the soft keyboard to show up once touched:
mMyText.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// forward the touch event to the view (for instance edit text will update the cursor to the touched position), then
// prevent the soft keyboard from popping up and consume the event
v.onTouchEvent(event);
disableSoftKeyboard(MyActivity.this);
return true;
}
});
whereas the method does more or less what you're doing already:
public void disableSoftKeyboard(#NonNull Activity activity) {
View view = activity.getCurrentFocus();
if (view != null) {
InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
} else {
activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
}
}
Hope it helps, and also that I didn't forget anything :)

Soft keyboard appears after Dialog is closed

Every time I have focus on some edit field and Dialog shows up, it will pull up soft keyboard as soon as I dismiss(); Dialog. I have tried every way to remove it after click event, but whatever I do it still shows up.
public static void hideSoftInput(FragmentActivity _activity){
if(_activity.getCurrentFocus() != null){
InputMethodManager inputManager = (InputMethodManager) _activity.getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(_activity.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
}
public static void hideSoftInput(View _v, Context _c){
if(_v.getWindowToken() != null){
InputMethodManager inputManager = (InputMethodManager) _c.getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(_v.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
}
I can't find it now but someone else on here suggested to wrap the call to hide the keyboard in a postDelayed call.
It worked for me when many other options failed. The only thing is that it may give a funny jiggle of the screen because you will be suppressing the keyboard while it is trying to show. Without the postDelayed it seems it will try to hide the keyboard before Android tries to show it after the dialog has closed. So ultimately we have to fight a timing issue in Android.
Something like this:
view.postDelayed(new Runnable()
{
#Override
public void run()
{
hideKeyboard();
}
}, 50);

Disable soft keyboard for an Edittext

I have an EditText where I want to handle the inputs myself, so I don't want the soft keyboard to show up when I click it (or when selection changes, focus changed, long clicked, etc). However, I still want to be able select the text, change cursor position, copy/past, etc.
I have tried putting android:windowSoftInputMode="stateAlwaysHidden" in the manifest, but that doesn't seems to do much. I also tried adding the following
edittext.setOnTouchListener(new OnTouchListener() {
#Override public boolean onTouch(View v, MotionEvent event) {
EditText edittext = (EditText) v;
int inType = edittext.getInputType(); // Backup the input type
edittext.setInputType(InputType.TYPE_NULL); // Disable standard keyboard
edittext.onTouchEvent(event); // Call native handler
edittext.setInputType(inType); // Restore input type
return true; // Consume touch event
}
});
which disables the keyboard, but also prevent the cursor from working.
Currently I'm basically trying to add listeners for all the situations where the keyboard might pop up to toggle it off, but this is very clunky and I can't catch all the cases. Is there a better way to disable the soft keyboard for a particular EditText or fragment?
Obviously the best solution would be if Google gave an inputType that works like this.
The following tends to work. It will sometimes flicker as the keyboard is loaded and then is instantly murdered. But, it just listens for when you click on the textview and then when that happens it murders the keyboard.
It can't account for things like if the textfield gets focus some other way, but for my purposes (I have a textfield for a barcode reader that gets a barcode read into it by a barcode reader (hardware keyboard)), so a softkeyboard makes no sense.
editView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm != null) {
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
//imm.hideSoftInputFromWindow(v.getWindowToken(), InputMethodManager.HIDE_IMPLICIT_ONLY);
}
}
});
I also added the other line you might want in there and commented it out. Namely if you want to hide the Android launched soft keyboard or if a user loads the keyboard by holding menu if that might close too.
Try this code.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Disable IME for this application
getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
setContentView(R.layout.activity_layout);

How to hide keyboard automatically after sending e-mail using emailIntent

There is a page where the user can send e-mail, sms or call its guests when needed. The problem is that when the user sends e-mail to its guest, the keyboard doesn't hide. Even-though I have a small problem solving the issue, It still seems hard to find alike post to solve it. I'll be also making screenshots and placing them in here.
As you can see, the keyboard doesn't hide after sending mail.
Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.setType("text/plain");
sendIntent.putExtra(Intent.EXTRA_EMAIL,
new String[] { **EmailAddress** });
startActivityForResult(sendIntent, 1);
#Override
protected void onActivityResult(int arg0, int arg1, Intent arg2) {
super.onActivityResult(arg0, arg1, arg2);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
InputMethodManager inputManager = (InputMethodManager) activity
.getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(**AnyViewOfScreen**.getWindowToken(),
InputMethodManager.HIDE_NOT_ALWAYS);
}
}, 300);
}
It is easy just add the following code in your manifest for the desire activity:
android:windowSoftInputMode="stateAlwaysHidden"
android:configChanges="keyboardHidden"
Its not the to override when the keyboard shows and hides itself, but here are the two methods I use to hide and show the keyboard as needed.
public void hideKeyboard(final View aView){
aView.post(new Runnable() {
#Override
public void run(){
InputMethodManager inputManager = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
}
}
public void showKeyboard(final View aView) {
aView.post(new Runnable() {
#Override
public void run() {
InputMethodManager inputMethodManager=(InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.toggleSoftInputFromWindow(ListingScreen.this.getCurrentFocus().getWindowToken(), InputMethodManager.SHOW_FORCED, 0);
}
});
}
When you call hide/show Keyboard, pass in your current view. The post runnable thread will wait to run until the view has finished loading, then dismiss the keyboard.
Hope this helps someone :
#Override
protected void onResume() {
super.onResume();
Log.d("OnResume", "Called");
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
InputMethodManager inputManager = (InputMethodManager) LocationDetailActivity.this
.getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(),
InputMethodManager.HIDE_NOT_ALWAYS);
}
}, 300);
}
if you do not have any focusable view in your layout, just add a dummy linear layout to your xml
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="true"
android:focusableInTouchMode="true">
<requestFocus />
</LinearLayout>
Call This method at the place where you want to hide your keyboard if it is opened(e.g call this when you click to sendingEmail button)
protected void showVirturalKeyboard()
{
Timer timer = new Timer();
timer.schedule(new TimerTask()
{
#Override
public void run()
{
InputMethodManager m = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
if(m != null)
{
m.toggleSoftInput(0, InputMethodManager.HIDE_IMPLICIT_ONLY);
}
}
}, 100);
}
After trying every solution I found on StackOverflow nothing seemed to worked. In the end I did find a way to force close the keyboard, but it is not ideal.
You can set android:windowSoftInputMode="adjustPan" in the Android Manifest for that activity.
The unfortunate side effect of this is explained here http://developer.android.com/guide/topics/manifest/activity-element.html#wsoft :
"The activity's main window is not resized to make room for the soft keyboard. Rather, the contents of the window are automatically panned so that the current focus is never obscured by the keyboard and users can always see what they are typing. This is generally less desirable than resizing, because the user may need to close the soft keyboard to get at and interact with obscured parts of the window."
I had similar problem. Gmail hides the keyboard after sending. When you return to your application it focuses on something else. If you take slower device you'll see that gmail hides keyboard after sending message.

Android TextField : set focus + soft input programmatically

In my view, I have a search EditText and I would like to trigger programmatically the behaviour of a click event on the field, i.e give focus to the text field AND display soft keyboard if necessary (if no hard keyboard available).
I tried field.requestFocus(). The field actually gets focus but soft keyboard is not displayed.
I tried field.performClick(). But that only calls the OnClickListener of the field.
Any idea ?
Good sir, try this:
edittext.setFocusableInTouchMode(true);
edittext.requestFocus();
I'm not sure, but this might be required on some phones (some of the older devices):
final InputMethodManager inputMethodManager = (InputMethodManager) context
.getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.showSoftInput(edittext, InputMethodManager.SHOW_IMPLICIT);
Here is the code that worked for me.
edittext.post(new Runnable() {
public void run() {
edittext.requestFocusFromTouch();
InputMethodManager lManager = (InputMethodManager)getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
lManager.showSoftInput(edittext, 0);
}
});
That's it! Enjoy ;)
The following code worked for me, after the other two answers didn't work for me:
#Override
public void onResume() {
super.onResume();
SingletonBus.INSTANCE.getBus().register(this);
//passwordInput.requestFocus(); <-- that doesn't work
passwordInput.postDelayed(new ShowKeyboard(), 300); //250 sometimes doesn't run if returning from LockScreen
}
Where ShowKeyboard is
private class ShowKeyboard implements Runnable {
#Override
public void run() {
passwordInput.setFocusableInTouchMode(true);
// passwordInput.requestFocusFromTouch();
passwordInput.requestFocus();
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
((InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE)).showSoftInput(passwordInput, 0);
}
}
After a successful input, I also make sure I hide the keyboard
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
((InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE))
.hideSoftInputFromWindow(getView().getWindowToken(), 0);
Technically, I just added 300 ms of delay before running the soft keyboard display request. Weird, right? Also changed requestFocus() to requestFocusFromTouch().
EDIT: Don't use requestFocusFromTouch() it gives a touch event to the launcher. Stick with requestFocus().
EDIT2: In Dialogs (DialogFragment), use the following
getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
instead of
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
In my case, I wanted to display the virtual keyboard with no reference to a specific textbox, so I used the first part of the accepted answer to focus :
edittext.setFocusableInTouchMode(true);
edittext.requestFocus();
Then I show the virtual keyboard :
InputMethodManager inputMethodManager = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
for kotlin, implement using extension function as follow
fun View.showSoftKeyboard() {
this.requestFocus()
val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.showSoftInput(this, InputMethodManager.SHOW_IMPLICIT)
}
field.post(new Runnable() {
#Override
public void run() {
field.requestFocus();
field.onKeyUp(KeyEvent.KEYCODE_DPAD_CENTER, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_CENTER));
}
});
In my case just this solved all problems:
val inputMethodManager: InputMethodManager =
context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
inputMethodManager.showSoftInput(edittext, InputMethodManager.SHOW_IMPLICIT)
I have put it in RecyclerView Adapter, because I use data binding.
Also I haven't used edittext.setFocusableInTouchMode(true) because in my layout it is true by default.
And don't use this line: edittext.requestFocus(). When I removed it, it started to work :)
val mAlertDialog = mBuilder.show()
//Coloca o foo no txtDlgQuantidade e então chama o teclado
mDialogView.txtDlgQuantidade.isFocusable = true
mDialogView.txtDlgQuantidade.isFocusableInTouchMode = true
mDialogView.txtDlgQuantidade.requestFocus()
mAlertDialog.window?.clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM)
mAlertDialog.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE)

Categories

Resources