I am writing a custom IME and there's something I don't understand in its lifecycle.
onStartInputView() and onFinishInputView() are supposed to be called when the keyboard view is displayed and destroyed, respectively. They're also called if the user changes app or text field while the soft keyboard is up. That's fine.
They weird case is that:
Given the soft keyboard is currently shown and I'm typing text (for instance, in my SMS app)
When I lock my device (turn the screen off)
Then I see a weird successions of calls:
onFinishInputView(finishingInput=true)
onStartInputView(editorInfo, restarting=false)
onFinishInputView(finishingInput=true)
onStartInputView(editorInfo, restarting=false)
onStartInputView() is the last call, so from the IME perspective the keyboard view is "visible" even though my device is locked (screen off).
My custom IME needs to know precisely when the keyboard is not displayed anymore (for instance to stop some background processing, or send a session close event): how can I do that since it seems I can't rely on onStartInputView()?
Thanks!
Related
I have a very simple UI that has one entry control to enter phone number and a button. The entry control has a handler for removing border around it. When the entry control got focus, keyboard pops up. But when I try to tap outside the entry control such as on the screen empty area, the keyboard does not dismiss and the entry control does not lose focus. Also since the button is at the bottom of the screen, therefore, the soft keyboard hides it and there is no way to tap the button. The button can only be tapped if I press the Android device back button.
At present, I have not checked this behavior on an iOS device.
This was not a problem in Xamarin Forms though. I searched a lot on Internet and found that it is currently a bug in MAUI.
I tried to attach a tap gesture on the parent layout control and invoked platform-specific code to hide the keyboard but it seems the entry does not lose focus and in turn the tap gesture event is never called.
However, the entry control should lose focus automatically when I tap outside the entry control (such as on the screen) and the soft keyboard should automatically dismiss.
Please provide a workaround if there is any.
Known bug. Removing the focus sometimes helps. Sometimes you need to do Disable/Enable in sequence. (I go with the second).
If you want, you can read this for example:
https://github.com/dotnet/maui/issues/12002
(Most disturbing part, considering this is know bug for half year+)
We can leave the behavior how this is for now in NET7 and provide an
API in NET8 that lets users toggle this behavior on/off for iOS and
Android
I am developing a soft keyboard. I have a class MyIME that extends InputMethodService.
I override onKey(int, int) to handle keypresses. My keyboard is able to insert and delete text the way I defined it just fine in portrait modes, I am just running into a problem in landscape when the keyboard is set to full screen.
In full screen mode, the framework's default ExtractEditLayout is used which contains an ExtractEditText instance. As I type in full screen mode, the following weird behavior happens:
I can type normal characters just fine. I insert these using getCurrentInputConnection().commitText(String.valueOf(code), 1);
When I press backspace to delete a character, the cursor moves back and the preceding character is removed. This behaves fine. Subsequent key strokes from this point on are no longer functioning as they are supposed to:
If I press backspace after the first one, the cursor moves backwards however the character does not get deleted. When backspace is pressed, getCurrentInputConnection().deleteSurroundingText(1, 0); is executed.
Similarly, if I add more characters after pressing backspace once, the cursor will move forward but the characters will not appear on the screen.
When I exit full screen mode by rotating my device back into portrait orientation, all of the characters that I typed or deleted are there. It appears as if the ExtractEditLayout used for composing fullscreen messages becomes out of sync with my InputMethodService subclass and it appears that they only become out of sync after I initially attempt to delete a character.
The bug was related to an expensive ExtractedTextRequest I was making each time I pressed backspace. The request was being used to determine if the text field was empty so I could determine whether or not to set the keyboard into a shifted state.
I got rid of the ExtractedTextRequest and now determine if the textfield is empty by a two (largish) calls to InputConnection's getTextBeforeCursor() and getTextAfterCursor() and the undesired behavior I described in the question component of this post no longer occurs.
What is the purpose of the method showSoftInput in class InputMethodManager? I am new to android, and well for me the documentation is not very clear :
Explicitly request that the current input method's soft input area be shown to the user, if needed. Call this if the user interacts with your view in such a way that they have expressed they would like to start performing input into it.
From what I have understood it opens the keyboard, am I am right? Why should we use this method, doesn't touching an EditText open automatically the keyboard??
No, touching an edit text doesn't automatically open a soft keyboard. That's just the default behavior. Under the hood, when you touch the edit text a series of events occurs. Eventually the Android framework will call showSoftInput on the IMS of the keyboard. This is the keyboard's chance to decide it doesn't want to show for some reason and return false if it is not shown. For example, I believe at Swype we overrode this not to show the keyboard if there was a hardware keyboard on the device already slid out, on the theory they then wanted to use the hardware keyboard.
Most of the time you're just going to either use the default implementation here, or do a few minor checks then fall back to the default implementation.
My Application needs to have two sources of input active at the same time: A bar-code scanner and the soft keyboard. When I pair a blue-tooth scanner, it is being treated as a physical keyboard. So, when this device is connected, the soft keyboard is not being displayed (soft keyboard is deactivated).
Is it possible to have both Physical Keyboard and Soft Keyboard active at the same time?
If not, what is the best approach towards solving the problem? Do I have to implement a custom View that sinks key press events? Is there any keyboard App on the Market that does this?
How do I, programatically, turn the Physical Keyboard On and Off? This is the toggle button 'Use Physical Keyboard' setting (I found the screenshot of this setting here:
It is not possible to have both Physical Keyboard and Soft keyboard active at the same time. It is enforced by InputMethodService function onEvaluateInputViewShown. you can check the documentation here.
/**
* Override this to control when the soft input area should be shown to
* the user. The default implementation only shows the input view when
* there is no hard keyboard or the keyboard is hidden. If you change what
* this returns, you will need to call {#link #updateInputViewShown()}
* yourself whenever the returned value may have changed to have it
* re-evaluated and applied.
*/
public boolean onEvaluateInputViewShown() {
So unless you are implementing your own IME wherein you can overide onEvaluateInputViewShown it is not possible to have both Physical and softkeyboard to be active at the same time.
Regarding your last question i am not sure but I think there is no way to programmatically hide the hardKeyboard. Though it doesn't have the solution you should check this question
I'd like to set focus to an EditText and automatically bring up the virtual keyboard in certain situations. However, if a phone's hardware keyboard is slid out, I wouldn't want to. Is there any way to detect whether or not a phone's hardware keyboard (if one exists) is slid out? Or is there some functionality of the EditText that will handle all this for me?
if (getResources().getConfiguration().hardKeyboardHidden==Configuration.HARDKEYBOARDHIDDEN_NO)
{
//do stuff
}
To dive deeper, triggering OnConfigurationChanged on keyboard slide is explained in Activity restart on rotation Android