android input method problems - android

A few questions about android:
Is it possible to replace the keys in default keyboards ? For example, is it possible to replace the dot in the numeric keyboard with a comma ?
I wrote a very simple IME, but I cannot set it to an EditText. What I want is to set one of my EditText to use the IME I wrote by default, not the default LatinIME. Is that possible ? How inputMethod attribute works ? I set the fully qualified class name of IME but it raises class not found exception.
Thanks.

Is it possible to replace the keys in default keyboards ?
You don't. Users are in control over their device, including what keyboard gets used.
But You can try to make some input methods
Read this tutorial: Creating an Input Method
clone this repo: LatinIME
And if replacing one character is your requirement, you can override text change listener of edittext, and check each entered character and if user entered dot then replace that with comma as
editText.addTextChangedListener(new TextWatcher(){
public void afterTextChanged(Editable s) {
//Check if s contains dot and replace it with comma
}
public void beforeTextChanged(CharSequence s, int start, int count, int after){}
public void onTextChanged(CharSequence s, int start, int before, int count){}
});
But this method executes each key hit in EditText.

try override this method.return another keyCode and see the reslt
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == someKeyCode) {
//...... button is pressed
}
return super.onKeyDown(keyCode, event);
}

Pretty sure replacing keys in the default keyboard is not possible, you would need to write your own keyboard replacement, much like all the keyboard Apps do.

Related

android - Enable caps lock (double click shift like) programatically on android

This question is different from all the others already asked here.
Problem & question
I want the caps lock enable like if I double click (or long press) the shift key, when opening the keyboard.
Another request is that the caps lock must be disable if the user presses the shift key.
I have already tried most of the proposed solutions in stackoverflow like android:inputType="textCapCharacters" or setAllCaps(true) but what happens is that the caps lock can't be disable. With the above solutions, upon pressing shift the user will insert one single character in lowercase and then the system automatically sets the keyboard back to caps lock.
This is not the correct way I want, I only want to have the caps enable the first time the user opens the keybaoard and then he will handle by himself the caps status.
Note
Keep in mind that I started the question with "like if I double click (or long press) the shift key", because using the inputType solution you have this situation:
That has not the white caps dash like if I manually enable caps lock:
I have found the solution to the problem!
I have to keep using android:inputType="textCapCharacters" but when the user presses the shift key and type a single character in lowercase, a textwatcher removes the flag textCapCharacters.
As follow the textwatcher that does the trick:
public class EditTextWatcher implements TextWatcher{
private EditText editText;
public PtlEditTextWatcher(EditText editText) {
this.editText = editText;
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) { }
#Override
public void afterTextChanged(Editable s) {
if (editText != null && s.length() > 0 && (editText.getInputType() & InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS) > 0)
if (Character.isLowerCase(s.toString().charAt(s.length() - 1)))
editText.setInputType(editText.getInputType() & ~InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS);
}
}
a simple use of it is:
addTextChangedListener(new EditTextWatcher(myEditText));

Android - catch backspace (delete) button on custom EditText

I want to catch the backspace/delete button event in soft keyboard on EditText custom.
How can I do it ?
I tried these solutions but they do not work for me :
Android custom EditText and back button override
EditText OnKeyDown
Get back key event on EditText
Android EditText delete(backspace) key event
Thanks for your help !
EDIT :
I found a fix for that isssue with the function DispatchKeyEvent :
#Override public boolean dispatchKeyEvent(#NonNull KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN
&& event.getKeyCode() == KeyEvent.KEYCODE_DEL) {
// ...
}
return super.dispatchKeyEvent(event);
}
I found a fix for that isssue with the function DispatchKeyEvent :
#Override public boolean dispatchKeyEvent(#NonNull KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN
&& event.getKeyCode() == KeyEvent.KEYCODE_DEL) {
// ...
}
return super.dispatchKeyEvent(event);
}
Catching Key Events from soft input methods in Android is unreliable. Here is an excerpt from the JavaDoc for the KeyEvent class:
As soft input methods can use multiple and inventive ways of inputting
text, there is no guarantee that any key press on a soft keyboard will
generate a key event: this is left to the IME's discretion, and in
fact sending such events is discouraged. You should never rely on
receiving KeyEvents for any key on a soft input method. In particular,
the default software keyboard will never send any key event to any
application targetting Jelly Bean or later, and will only send events
for some presses of the delete and return keys to applications
targetting Ice Cream Sandwich or earlier.
One workaround could involve using TextWatcher. Whenever a delete occurs in an EditText, the character count drops.
myEditText.addTextChangedListener(this);
//...
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (count == 0) {
//text was deleted.
}
}
Edit: This is untested, so may not be completely reliable. In addition, it's worth pointing out that count may also read 0 if a long section of text is selected and then replaced. I created a library once that was designed to add Undo/Redo functionality to EditText, but can also identify the difference between text being replaced and deleted, so this may be of use to you if you require more accuracy.
Please, take a look at a solution I provided in another similar topic: Android - cannot capture backspace/delete press in soft. keyboard. You need to build your custom EditText class and override onCreateInputConnection method in it. It will give you access to deleteSurroundingText event which is firing when you click backspace. I've tested it in some devices and hope it will work in others also. Try it and give a feedback.
Here you go..
editText.addTextChangedListener(new TextWatcher() {
private int before;
private int after;
private int prevLength;
private boolean isBackPressed;
ArrayList<Integer> arrayList;
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
prevLength = charSequence.length();
}
#Override
public void onTextChanged(CharSequence charSequence, int start, int end, int count) {
}
#Override
public void afterTextChanged(Editable editable) {
isBackPressed = prevLength > editable.length();
if(isBackPressed){
Toast.makeText(getApplicationContext(),"Back",Toast.LENGTH_LONG).show();
}
}
});

Space Key event behaviour on Numeric Input field?

I created two EditText with "android:inputType="number" property.
here I am using hardware Keyboard, so when I perform Space Key event on textField, focus control directly shift from editText view to some other random view of screen. In normal text field type it took it as an another character, that's fine.
Any one have idea how can use Space key event to retain focus on same field.
Using editText.setInputType(InputType.TYPE_CLASS_NUMBER) may probably solve your problem.
Change/Add your EditText Property with android:imeOptions="actionNext" like as follows
<EditText
android:id="#+id/edit_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:imeOptions="actionNext"
android:inputType="text" />
Or with android:imeOptions="actionNone" for default behavior of EditText
<EditText
android:id="#+id/edit_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:imeOptions="actionNone"
android:inputType="text" />
So it looks like your problem doesn't have to do with the 'input' type of your EditText, but rather the key press events coming from the keyboard....
So 'hopefully' this should fix your problem for you (by 'skipping over' the 'next' event from the 'space' button being pressed.)
// do for both EditText(s)
editText1.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
log.d("main","KeyPress:"+ actionID);
if (event != null ) { log.d("main","KeyPress:" + event.getKeyCode() ); }
if ( actionId == EditorInfo.IME_ACTION_NEXT) {
// do 'nothing' or 'add a space' if you want that
return true;
}
return false;
}
});
This is likely what is happening (hard to tell without your XML)
So I found something that should help you figure out the pattern + possibly lead to solving it... from https://stackoverflow.com/a/17990096
if there is a android:nextFocus.... setting in your XML (or equivalent in code) and/or the physical keyboard 'space' is also signalling IME_ACTION_NEXT (or another IME action similar to it)
If the EditorInfo.IME_ACTION_NEXT isn't the IME action that is causing your problems, then you can try this... to determine WHAT is.
from: https://stackoverflow.com/a/4171427
if you have PHYSICAL keyboard you can use to detect keyDown events and handle them appropriately,
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
log.d("main","KeyPress:" + keyCode);
if (event != null ) { log.d("main","KeyPress:" + event.getKeyCode() ); }
// if you want to 'handle' the keyPess here, best to use switch like below
// switch (keyCode) {
// case KeyEvent.KEYCODE_A:
// {
// //your Action code
// return true;
// }
/// }
return super.onKeyDown(keyCode, event);
}
BUT... if you have software keyboard You need to use addTextChangedListener/TextWatcher Because the physical key press is 'eaten' by the EditText (from what I saw in another post, but seems to be correct from my testing.)
mMyEditText.addTextChangedListener(new TextWatcher()
{
public void afterTextChanged(Editable s)
{
}
public void beforeTextChanged(CharSequence s, int start, int count, int after)
{
/*This method is called to notify you that, within s, the count characters beginning at start are about to be replaced by new text with length after. It is an error to attempt to make changes to s from this callback.*/
}
public void onTextChanged(CharSequence s, int start, int before, int count)
{
}
);
You can override what the EditText does when a 'space' is entered.
This seems pretty easy when in 'software keyboard', but physical keyboard seems to be a bit more difficult.
https://developer.android.com/reference/android/widget/TextView.OnEditorActionListener.html
Similar to this question (but 'space' instead of 'enter') Android - Handle "Enter" in an EditText
This could help you determine the 'pattern' of the focus being changed. if it is random or not (most likely -not- random, but possibly 'interesting' to look into)
http://developer.android.com/reference/android/view/View.OnFocusChangeListener.html
// try this to see
View.OnFocusChangeListener changeListener = new View.OnFocusChangeListener()
{
#Override
public void onFocusChange(View v, boolean hasFocus) {
log.d("YourClassName", "FocusChanged" + hasFocus)
}
};
EditText1.setOnFocusChangeListener(changeListener);
EditText2.setOnFocusChangeListener(changeListener);
Button.setOnFocusChangeListener(changeListener);
// ... etc... (add to views to see if there is pattern)

Prevent ' Enter key ' to trigger TextWatcher

I was making an application to act as remote keyboard where user will click on an edittext and type and corresponding alphabets will b typed in computer.
I have detected variaous alphabets and numbers with the help of TextWatcher and sent them to my server successfully.
Problem comes when user presses enter key. This also triggers TextWatcher . and since i am sending the latest entered changes , error shows up on server side.
As a solution what i did is , set one onkeylistener as well which will detect the enter key and perform action and CONSUME it , but unfortunately in that case also first textwatcher gets triggered and then onkeylistener.
Here is the code of my onkeylistener
keyboard.setOnKeyListener(new OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_ENTER&&event.getAction()==KeyEvent.ACTION_UP){
out.println("enter");
return true;
}
return false;
}
});
Code of TextWatcher :
private TextWatcher watcher = new TextWatcher() {
public void onTextChanged(CharSequence s, int start, int before, int count) {
if(count>0){
out.println(":"+s.subSequence(start, start+count).toString());
}
}
.
.
.
Problem is on pressing enter key it fires TextWatcher's onTextChanged as well as onkeylistener. whereas i want only on key listener to fire.
I want to fire Textwatcher only in case of alphabets , numbers , some symbols etc.
Also if you can suggest different approach for detecting and sending characters ( soft ) will be great .
Ok i think i solved it. in Textwatcher add this if statement:
if(s.toString().substring(start).contains("\n"))
in that way if last key entered was 'enter' then it would go into this is and then u can perform whatever u want.

Android EditText change focus after validation and showing the error in a Dialog

I have a simple Activity with 3 EditText fields.
User, Pass, Confirmation
After typing something in the User field and the person clicks next on the keyboard, I have a setOnFocusChangeListener on there that will validate the input. If the validation fails a Dialog opens with a message and an OK button.
After the Dialog is closed I tried a requestFocus on my User EditText in many variations, by releasing it on Pass, by trying to release on User again, by requesting than clearing and requesting again but when I click on another field the softkeyboard won't open again or I end up with two EditText fields with the blinking cursor.
Any ideas?
I suggest validating the user's input with a TextWatcher:
EditText textbox = new EditText(context);
textbox.addTextChangedListener(new TextWatcher() {
#Override
public void afterTextChanged(Editable s) {
// Your validation code goes here
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
});
Only handle validation in the afterTextChanged method, don't touch the other two, as advised in the documentation. However afterTextChanged get's fired, every time the input changes, so if the user enters the word "hello" this method get's called when h is entered, then again when e is entered and so on... Furthermore, if you modify the edittext value in afterTextChanged, the method get's called too.
An alternative is to validate the user input when the EditText loses focus. For this purpose you could use:
textbox.setOnFocusChangeListener(new OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
// Your validation code goes here
}
});
However beware, that some widgets might not grab focus, so your Edittext never loses it (had that with Buttons for instance).
Furthermore the EditText offers a setError method, which marks the edittext with a red error mark and shows the text passed to setError to the user (the text can be set by you when calling setError("Your error message")).

Categories

Resources