Injecting non-English characters in Android - android

I am programming on a remote control app. One of the tasks is injecting characters. The code I am currently using looks like this:
Instrumentation instr = new Instrumentation();
String str="a";
// basically the same like calling instr.sendStringSync(str);
char[] chars = str.toCharArray();
KeyCharacterMap keyCharacterMap = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD);
KeyEvent[] keyEvents = keyCharacterMap.getEvents(chars);
if (keyEvents != null) {
for (KeyEvent kev : keyEvents) {
instr.sendKeySync(kev);
}
}
That works perfectly on English characters (The characters show up in EditText boxes). However, if I am trying to inject e.g. Korean characters, this fails. The function getEvents returns null, even when I have configured Korean language and keyboard.
I know there is another method for injecting strings directly:
KeyEvent event = new KeyEvent(SystemClock.uptimeMillis(), str, 0, 0);
instr.sendKeySync(event);
This is not working either - no characters shown in EditText boxes, and onKeyMultiple() is not called either in my test activity.
This is strange since dispatchKeyEvent() with the same event works in my test activity:
KeyEvent event = new KeyEvent(SystemClock.uptimeMillis(), str, 0, 0);
dispatchKeyEvent(event);
My remote control app needs to inject events no matter to which activity. This is possible using Instrumentation (with android.permission.INJECT_EVENTS and a signature with the platform key).
How can I inject non-English characters using instrumentation?
Is there another way to accomplish this? E.g. Using dispatchKeyEvent (has to work for other activities/apps as well).

I leave the part above as extra info. I have found a solution. It requires to have root, but if you can sign with the application key I guess that's not a problem. What you can do is edit the file Virtual.kcm (/system/usr/keychars/Virtual.kcm), which is the default key character map (kcm). You can add any character you want, and then use the method Instrumentation.sendStringSync(String string), because it will be able to generate KeyEvents from the new kcm.
I had some problems editting the kcm on the phone, so what I did was to copy it on a computer, edit it there and then copy it back to the device.
I hope this helps!
In this link, the following content appears. It seams that the virtual keyboard has a US keyCharacterMap and layout, no matter what you choose on settings. I haven't been able to find a way to solve this.
Language Note
Android does not currently support multilingual keyboards. Moreover, the built-in generic key character map assumes a US English keyboard layout.
OEMs are encouraged to provide custom key character maps for their keyboards if they are designed for other languages.
Future versions of Android may provide better support for multilingual keyboards or user-selectable keyboard layouts.

You can use this method and InputFilter for EditText:
private boolean isLatinSymbolOrDigit(char c)
{
// Allow [a-zA-Z0-9]
if ('0' <= c && c <= '9')
return true;
if ('a' <= c && c <= 'z')
return true;
if ('A' <= c && c <= 'Z')
return true;
return false;
}
InputFilter filter = new InputFilter()
{
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend)
{
for (int i = start; i < end; i++)
{
if (isLatinSymbolOrDigit(source.charAt(i)))
{
}
else
{
//wrong character
return "";
}
}
return null;
}
};
editText.setFilters(new InputFilter[] {filter});

Related

How to disable emojis programmatically in Android

I want to hide emojis and auto suggestions from keyboard programmatically. Its working in some Android devices but not in all devices. here's my code for hide auto suggestions:
txtSingupemail.setInputType(InputType.TYPE_TEXT_VARIATION_FILTER | InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS
|InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
txtSignuppwd.setInputType(InputType.TYPE_TEXT_VARIATION_FILTER | InputType.TYPE_TEXT_VARIATION_PASSWORD);
txtSignuppwd.setTransformationMethod(PasswordTransformationMethod.getInstance());
Here's the snapshot of my UI:
This is layout when user clicks signIn button. When user tap on bottom left icon which is marked red, the keyboard height goes increase due to emojis as suggestions.
See below snapshot:
Is there any way to hide those top emojis from keyboard programmatically?
Try this it's works for me
editText.setFilters(new InputFilter[]{new EmojiExcludeFilter()});
private class EmojiExcludeFilter implements InputFilter {
#Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
for (int i = start; i < end; i++) {
int type = Character.getType(source.charAt(i));
if (type == Character.SURROGATE || type == Character.OTHER_SYMBOL) {
return "";
}
}
return null;
}
}
There are hundreds, if not thousands, of input method editors (a.k.a., soft keyboards) for Android.
None have to offer emoji. Those that do are welcome to offer them however they want, whenever they want.
There is no requirement for an input method editor to honor any flags that you put on the EditText. Therefore, there is no requirement for an input method editor to offer any means of blocking emoji input. And, even if some do offer this ability, others might not, and those that do might do so via different flags.
The decision of whether to have an emoji option on the keyboard is between the developers of the keyboard and the user (who chooses the keyboard to use). You do not get a vote.
Since AFAIK emoji are just Unicode characters, and since you should be supporting Unicode characters elsewhere (e.g., Chinese glyphs), it is unclear what technical reason you would have to avoid emoji. That being said, you are welcome to attempt to filter them out of the text being entered (e.g., use TextWatcher), if you are opposed to emoji.
It's probably not the best solution but the code below worked for me just fine:
editText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
and since the password input type changes the font you just set the default typeface to it:
editText.setTypeface(Typeface.DEFAULT);
For Android
mEditText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD| TEXT_MULTILINE);
TYPE_TEXT_VARIATION_VISIBLE_PASSWORD - We use Password char as Text input for EditTest. It doesn't have emojis and email keys like .com and # keys TEXT_MULTILINE - This will change the keyboard layout button [Done] or [->] to [Enter] key so we can use multi line text or new line feature.
In Xamarin Form
Create a CustomRender and in OnElementChanged method
protected override void OnElementChanged(ElementChangedEventArgs e)
{
base.OnElementChanged(e);
if (Control != null)
{
Control.ImeOptions = Android.Views.InputMethods.ImeAction.Done;
Control.InputType = Android.Text.InputTypes.ClassText | Android.Text.InputTypes.TextVariationVisiblePassword| Android.Text.InputTypes.TextFlagMultiLine;
Control.SetTypeface(Typeface.Default, TypefaceStyle.Normal);
}
}
This might be helpful for you it will disable emojis android:inputType="textShortMessage" . Please let me know if it doesn't help you
In Kotlin, add Input filter to Edittext. I faced issues when digits and alphabets were rapidly typed. This code solves that
editText.filters = editTextAllowAlphabetsSymbols("") // Add any symbols that you wish to allow
then this
fun editTextAllowAlphabetsSymbols(symbols:String):Array<InputFilter>{
return arrayOf(AlphabetsSymbolsInputFilter(symbols))
}
and finally
class AlphabetsSymbolsInputFilter(symbols:String) : InputFilter {
private var mWordPattern: String
var mLetterPattern:String
init {
mLetterPattern = "[a-zA-Z.$symbols ]"
//mLetterPattern = "[a-zA-Z0-9.$symbols ]" // replace if alphanumeric
mWordPattern = "$mLetterPattern+"
}
override fun filter(source: CharSequence, start: Int, end: Int, dest: Spanned, dstart: Int, dend: Int): CharSequence? {
if(source == ""){
println("In backspace")
return source
}
if(source.isNotEmpty() && source.toString().matches(mWordPattern.toRegex())){
return source
}
var sourceStr = ""
if(source.isNotEmpty() && !source.toString().matches(mLetterPattern.toRegex())){
sourceStr = source.toString()
while(sourceStr.isNotEmpty() && !sourceStr.matches(mWordPattern.toRegex())){
println(" source --> $source dest ---> $dest")
if(sourceStr.last().isDigit()) {
print("Is digit ")
sourceStr = sourceStr.subSequence(0, sourceStr.length - 1).toString()
}
else if(!sourceStr.last().toString().matches(mLetterPattern.toRegex())) {
print("Is emoji or weird symbols")
sourceStr = sourceStr.subSequence(0, sourceStr.length - 1).toString()
}else
break
}
return sourceStr
}
return source
}
}
Best method till now and works in good maaner in your xml write
android:digits= "ABCDEFGHIJKLMNOPQRSTUVWXYZqwertyuiopasdfghjklmnbvcxz#.,1234567890"
Try This
There is nothing that will 100% disable emoji.You can only hide default emos of keyboard whatever if someone is using custom keyboard,you can't hide the emos of custom keyboard
may be this will help you
editext.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL);

character mapping in edittext android

I want to make my edittext like when I write character "g" it's related mapping custom character should written like here in Hindi it's "เคœเฅ€"
I think there should be character mapping but having no knowledge can anybody help me
how to do that
Other app https://play.google.com/store/apps/details?id=nichetech.hindi.editor is also doing same like this way, there is option available offline and online
Online is doing with help of google translator but if I choose Offline then writing happen like this way
Here you can see that Keyboard is English, but writing is done in Hindi language
Thanks
Is there way that I write in English and it's related mapping character will written in EditText of my application only.
Does anybody done like this way then please help me, how to do that
To accomplish what you're after, I would create a HashMap of chars that map to other chars. If some specific char is not mapped just print it out. Here's an example I've put up:
final HashMap<Character, Character> charMap = new HashMap<Character, Character>();
charMap.put('q', '1');
charMap.put('w', '2');
charMap.put('e', '3');
charMap.put('r', '4');
charMap.put('t', '5');
charMap.put('y', '6');
final EditText editText = (EditText) findViewById(R.id.editText);
editText.addTextChangedListener(new TextWatcher() {
boolean replaced;
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
Log.e("TAG", start + " " + before + " " + count);
// Check in lower case
String oldStr = s.toString().toLowerCase();
StringBuilder newStr = new StringBuilder(s);
// Loop through changed chars
for (int i = 0; i < count; i++) {
// Replace if a substitution is avaiable
Character replacement = charMap.get(oldStr.charAt(start + i));
if (replacement != null) {
replaced = true;
newStr.setCharAt(start + i, replacement);
}
}
if (replaced) {
replaced = false;
editText.setText(newStr);
// Move cursor after the new chars
editText.setSelection(start + count);
}
}
#Override
public void afterTextChanged(Editable s) {
}
});
Pros:
Ignores case when looking for a replacement. (q = Q = 1)
Replaces immediately single and multiple chars
Doesn't loop the whole string
Can replace in the middle of another string
Cons:
You have to have a HashMap entry for every character you want replaced
...
As a side-note I'd like to name a few limitations that your given app's "online version" has:
The converting is done only when a space, new line or punctuation mark is entered.
You cannot add letters to already converted words.
The apps "offline" version also has a minor bug:
It doesn't convert words that are copied in or written with Swipe
Key character map files (.kcm files) are responsible for mapping combinations of Android key codes with modifiers to Unicode characters.Device-specific key layout files are required for all internal (built-in) input devices that have keys, if only to tell the system that the device is special purpose only (not a full keyboard).
Device-specific key layout files are optional for external keyboards, and often aren't needed at all. The system provides a generic key character map that is suitable for many external keyboards.
If no device-specific key layout file is available, then the system will choose a default instead.
Key character map files are located by USB vendor, product (and optionally version) id or by input device name.
Key character map files are located by USB vendor, product (and optionally version) id or by input device name.
Suppose the user pressed A and SHIFT together. The system first locates the set of properties and behaviors associated with KEYCODE_A.
key A {
label: 'A'
base: 'a'
shift, capslock: 'A'
ctrl, alt, meta: none
}
ey ESCAPE {
base: fallback BACK
alt, meta: fallback HOME
ctrl: fallback MENU
}
key A {
label: 'A'
number: '2'
base: 'a'
shift, capslock: 'A'
alt: '#'
shift+alt, capslock+alt: none
}
key SPACE {
label: ' '
number: ' '
base: ' '
shift: ' '
alt: '\uef01'
shift+alt: '\uef01'
}
I guess you are better off looking at creating your own *.ttf file with all character mappings. You can just set it on your EditText (or whatever text widget you are using). TTF fonts are welcome in assets/ directory (or any directory you can read from). You can create Typeface object with:
Typeface.createFromAsset(AssetManager mgr, String path)
and setting it with:
textView.setTypeface(mTypeface);
public void MapCharacter() {
this.singleChar.put((Object)"a", (Object)"\u0905");
this.singleChar.put((Object)"b", (Object)"\u092c");
this.singleChar.put((Object)"c", (Object)"\u091a");
this.singleChar.put((Object)"d", (Object)"\u0926");
this.singleChar.put((Object)"e", (Object)"\u090f");
this.singleChar.put((Object)"f", (Object)"\u092b");
this.singleChar.put((Object)"g", (Object)"\u0917");
this.singleChar.put((Object)"h", (Object)"\u0939");
this.singleChar.put((Object)"i", (Object)"\u0907");
this.singleChar.put((Object)"j", (Object)"\u091c");
this.singleChar.put((Object)"k", (Object)"\u0915");
this.singleChar.put((Object)"l", (Object)"\u0932");
this.singleChar.put((Object)"m", (Object)"\u092e");
this.singleChar.put((Object)"n", (Object)"\u0928");
this.singleChar.put((Object)"o", (Object)"\u0913");
this.singleChar.put((Object)"p", (Object)"\u092a");
this.singleChar.put((Object)"q", (Object)"");
this.singleChar.put((Object)"r", (Object)"\u0930");
this.singleChar.put((Object)"s", (Object)"\u0938");
this.singleChar.put((Object)"t", (Object)"\u0924");
this.singleChar.put((Object)"u", (Object)"\u0909");
this.singleChar.put((Object)"v", (Object)"\u0935");
this.singleChar.put((Object)"w", (Object)"\u0935");
this.singleChar.put((Object)"x", (Object)"\u0915\u094d\u0937");
this.singleChar.put((Object)"y", (Object)"\u092f");
this.singleChar.put((Object)"z", (Object)"\u091d");
this.singleChar.put((Object)"A", (Object)"\u0906");
this.singleChar.put((Object)"B", (Object)"\u092c");
this.singleChar.put((Object)"C", (Object)"\u091a");
this.singleChar.put((Object)"D", (Object)"\u0921");
this.singleChar.put((Object)"E", (Object)"\u090d");
this.singleChar.put((Object)"F", (Object)"\u092b");
this.singleChar.put((Object)"G", (Object)"\u0917");
this.singleChar.put((Object)"H", (Object)"\u0903");
this.singleChar.put((Object)"I", (Object)"\u0908");
this.singleChar.put((Object)"J", (Object)"\u091c");
this.singleChar.put((Object)"K", (Object)"\u0915");
this.singleChar.put((Object)"L", (Object)"\u0933");
this.singleChar.put((Object)"M", (Object)"\u0902");
this.singleChar.put((Object)"N", (Object)"\u0923");
this.singleChar.put((Object)"O", (Object)"\u0911");
this.singleChar.put((Object)"P", (Object)"\u092a");
this.singleChar.put((Object)"Q", (Object)"");
this.singleChar.put((Object)"R", (Object)"\u0930");
this.singleChar.put((Object)"S", (Object)"\u0936");
this.singleChar.put((Object)"T", (Object)"\u091f");
this.singleChar.put((Object)"U", (Object)"\u090a");
this.singleChar.put((Object)"V", (Object)"\u0935");
this.singleChar.put((Object)"W", (Object)"\u0935");
this.singleChar.put((Object)"X", (Object)"\u0915\u094d\u0937");
this.singleChar.put((Object)"Y", (Object)"\u092f");
this.singleChar.put((Object)"Z", (Object)"\u091d");
this.singleChar.put((Object)"1", (Object)"\u0967");
this.singleChar.put((Object)"2", (Object)"\u0968");
this.singleChar.put((Object)"3", (Object)"\u0969");
this.singleChar.put((Object)"4", (Object)"\u096a");
this.singleChar.put((Object)"5", (Object)"\u096b");
this.singleChar.put((Object)"6", (Object)"\u096c");
this.singleChar.put((Object)"7", (Object)"\u096d");
this.singleChar.put((Object)"8", (Object)"\u096e");
this.singleChar.put((Object)"9", (Object)"\u096f");
this.singleChar.put((Object)"0", (Object)"\u0966");
this.singleChar.put((Object)"#", (Object)"\u0953");
this.singleChar.put((Object)"$", (Object)" \u0951");
this.singleChar.put((Object)"^", (Object)"\u094d");
this.singleChar.put((Object)":", (Object)"\u0903");
this.delimtrChar.put((Object)" ", (Object)" ");
this.delimtrChar.put((Object)"!", (Object)"!");
this.delimtrChar.put((Object)"#", (Object)"\u0970");
this.delimtrChar.put((Object)"%", (Object)"%");
this.delimtrChar.put((Object)"&", (Object)"\u093d");
this.delimtrChar.put((Object)"(", (Object)"(");
this.delimtrChar.put((Object)")", (Object)")");
this.delimtrChar.put((Object)"~", (Object)"~");
this.delimtrChar.put((Object)"`", (Object)"`");
this.delimtrChar.put((Object)"_", (Object)"_");
this.delimtrChar.put((Object)"=", (Object)"=");
this.delimtrChar.put((Object)"{", (Object)"{");
this.delimtrChar.put((Object)"}", (Object)"}");
this.delimtrChar.put((Object)"|", (Object)"\u0964");
this.delimtrChar.put((Object)"\"", (Object)"\"");
this.delimtrChar.put((Object)"<", (Object)"<");
this.delimtrChar.put((Object)">", (Object)">");
this.delimtrChar.put((Object)"?", (Object)"?");
this.delimtrChar.put((Object)"+", (Object)"+");
this.delimtrChar.put((Object)"-", (Object)"-");
this.delimtrChar.put((Object)"[", (Object)"[");
this.delimtrChar.put((Object)"]", (Object)"]");
this.delimtrChar.put((Object)"\\", (Object)"\\");
this.delimtrChar.put((Object)";", (Object)";");
this.delimtrChar.put((Object)"'", (Object)"'");
this.delimtrChar.put((Object)",", (Object)",");
this.delimtrChar.put((Object)".", (Object)".");
this.delimtrChar.put((Object)"/", (Object)"/");
this.doubleChar.put((Object)"aa", (Object)"\u0906");
this.doubleChar.put((Object)"ai", (Object)"\u0910");
this.doubleChar.put((Object)"au", (Object)"\u0914");
this.doubleChar.put((Object)"ou", (Object)"\u0914");
this.doubleChar.put((Object)"ee", (Object)"\u0908");
this.doubleChar.put((Object)"oo", (Object)"\u090a");
this.doubleChar.put((Object)"aM", (Object)"\u0905\u0902");
this.doubleChar.put((Object)"aM~", (Object)"\u0905\u0901");
this.doubleChar.put((Object)"aH", (Object)"\u0905\u0903");
this.doubleChar.put((Object)"a:", (Object)"\u0905\u0903");
this.doubleChar.put((Object)"NG", (Object)"\u0919");
this.doubleChar.put((Object)"OM", (Object)"\u0950");
this.doubleChar.put((Object)"+~", (Object)"\u5350");
this.doubleChar.put((Object)"Rs", (Object)"\u20b9");
this.doubleChar.put((Object)"||", (Object)"\u0965");
this.doubleChar.put((Object)"NY", (Object)"\u091e");
this.doubleChar.put((Object)"Gy", (Object)"\u091c\u094d\u091e");
this.doubleChar.put((Object)"kh", (Object)"\u0916");
this.doubleChar.put((Object)"gh", (Object)"\u0918");
this.doubleChar.put((Object)"Ch", (Object)"\u091b");
this.doubleChar.put((Object)"chh", (Object)"\u091b");
this.doubleChar.put((Object)"ch", (Object)"\u091a");
this.doubleChar.put((Object)"th", (Object)"\u0925");
this.doubleChar.put((Object)"Th", (Object)"\u0920");
this.doubleChar.put((Object)"dh", (Object)"\u0927");
this.doubleChar.put((Object)"Dh", (Object)"\u0922");
this.doubleChar.put((Object)"jh", (Object)"\u091d");
this.doubleChar.put((Object)"ph", (Object)"\u092b");
this.doubleChar.put((Object)"bh", (Object)"\u092d");
this.doubleChar.put((Object)"sh", (Object)"\u0936");
this.doubleChar.put((Object)"Sh", (Object)"\u0937");
this.doubleChar.put((Object)"kSh", (Object)"\u0915\u094d\u0937");
this.doubleChar.put((Object)"Ri", (Object)"\u090b");
this.doubleChar.put((Object)"RI", (Object)"\u0960");
this.doubleChar.put((Object)"Li~", (Object)"\u090c");
this.doubleChar.put((Object)"LI~", (Object)"\u0961");
this.doubleChar.put((Object)"##", (Object)"\u0971");
this.doubleChar.put((Object)"$$", (Object)"\u0952");
this.matraChar.put((Object)"a", (Object)"\u093e");
this.matraChar.put((Object)"A", (Object)"\u093e");
this.matraChar.put((Object)"i", (Object)"\u093f");
this.matraChar.put((Object)"I", (Object)"\u0940");
this.matraChar.put((Object)"u", (Object)"\u0941");
this.matraChar.put((Object)"U", (Object)"\u0942");
this.matraChar.put((Object)"e", (Object)"\u0947");
this.matraChar.put((Object)"E", (Object)"\u0945");
this.matraChar.put((Object)"o", (Object)"\u094b");
this.matraChar.put((Object)"O", (Object)"\u0949");
this.matraChar.put((Object)"ai", (Object)"\u0948");
this.matraChar.put((Object)"au", (Object)"\u094c");
this.matraChar.put((Object)"ou", (Object)"\u094c");
this.matraChar.put((Object)"aa", (Object)"\u093e");
this.matraChar.put((Object)"oo", (Object)"\u0942");
this.matraChar.put((Object)"ee", (Object)"\u0940");
this.matraChar.put((Object)"*", (Object)"\u093c");
this.matraChar.put((Object)"M~", (Object)"\u0901");
this.matraChar.put((Object)"r", (Object)"\u094d\u0930");
this.matraChar.put((Object)"R", (Object)"\u0930\u094d");
this.matraChar.put((Object)"Ri", (Object)"\u0943");
this.matraChar.put((Object)"RI", (Object)"\u0944");
this.matraChar.put((Object)"Li~", (Object)"\u0962");
this.matraChar.put((Object)"LI~", (Object)"\u0963");
}

Android - How to filter emoji (emoticons) from a string?

I'm working on an Android app, and I do not want people to use emoji in the input.
How can I remove emoji characters from a string?
Emojis can be found in the following ranges (source) :
U+2190 to U+21FF
U+2600 to U+26FF
U+2700 to U+27BF
U+3000 to U+303F
U+1F300 to U+1F64F
U+1F680 to U+1F6FF
You can use this line in your script to filter them all at once:
text.replace("/[\u2190-\u21FF]|[\u2600-\u26FF]|[\u2700-\u27BF]|[\u3000-\u303F]|[\u1F300-\u1F64F]|[\u1F680-\u1F6FF]/g", "");
Latest emoji data can be found here:
http://unicode.org/Public/emoji/
There is a folder named with emoji version.
As app developers a good idea is to use latest version available.
When You look inside a folder, You'll see text files in it.
You should check emoji-data.txt. It contains all standard emoji codes.
There are a lot of small symbol code ranges for emoji.
Best support will be to check all these in Your app.
Some people ask why there are 5 digit codes when we can only specify 4 after \u.
Well these are codes made from surrogate pairs. Usually 2 symbols are used to encode one emoji.
For example, we have a string.
String s = ...;
UTF-16 representation
byte[] utf16 = s.getBytes("UTF-16BE");
Iterate over UTF-16
for(int i = 0; i < utf16.length; i += 2) {
Get one char
char c = (char)((char)(utf16[i] & 0xff) << 8 | (char)(utf16[i + 1] & 0xff));
Now check for surrogate pairs. Emoji are located on the first plane, so check first part of pair in range 0xd800..0xd83f.
if(c >= 0xd800 && c <= 0xd83f) {
high = c;
continue;
}
For second part of surrogate pair range is 0xdc00..0xdfff. And we can now convert a pair to one 5 digit code.
else if(c >= 0xdc00 && c <= 0xdfff) {
low = c;
long unicode = (((long)high - 0xd800) * 0x400) + ((long)low - 0xdc00) + 0x10000;
}
All other symbols are not pairs so process them as is.
else {
long unicode = c;
}
Now use data from emoji-data.txt to check if it's emoji.
If it is, then skip it. If not then copy bytes to output byte array.
Finally byte array is converted to String by
String out = new String(outarray, Charset.forName("UTF-16BE"));
For those using Kotlin, Char.isSurrogate can help as well. Find and remove the indexes that are true from that.
Here is what I use to remove emojis. Note: This only works on API 24 and forwards
public String remove_Emojis_For_Devices_API_24_Onwards(String name)
{
// we will store all the non emoji characters in this array list
ArrayList<Character> nonEmoji = new ArrayList<>();
// this is where we will store the reasembled name
String newName = "";
//Character.UnicodeScript.of () was not added till API 24 so this is a 24 up solution
if (Build.VERSION.SDK_INT > 23) {
/* we are going to cycle through the word checking each character
to find its unicode script to compare it against known alphabets*/
for (int i = 0; i < name.length(); i++) {
// currently emojis don't have a devoted unicode script so they return UNKNOWN
if (!(Character.UnicodeScript.of(name.charAt(i)) + "").equals("UNKNOWN")) {
nonEmoji.add(name.charAt(i));//its not an emoji so we add it
}
}
// we then cycle through rebuilding the string
for (int i = 0; i < nonEmoji.size(); i++) {
newName += nonEmoji.get(i);
}
}
return newName;
}
so if we pass in a string:
remove_Emojis_For_Devices_API_24_Onwards("๐Ÿ˜Š test ๐Ÿ˜Š Indic:เคข Japanese:ใช ๐Ÿ˜Š Korean:ใ…‚");
it returns: test Indic:เคข Japanese:ใช Korean:ใ…‚
Emoji placement or count doesn't matter

Converting a character into keycode

I have a character and I want to convert it into KeyEvent KeyCode constraints http://developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_0
Like if I have a character '0' I wan to convert into
Key code constant: '0' key.
Constant Value: 7 (0x00000007)
as specified in the KeyEvent page. What can be a best method for doing this? Is there any predefined function to do it?
Here is a solution I use to put chars in a webview:
char[] szRes = szStringText.toCharArray(); // Convert String to Char array
KeyCharacterMap CharMap;
if(Build.VERSION.SDK_INT >= 11) // My soft runs until API 5
CharMap = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD);
else
CharMap = KeyCharacterMap.load(KeyCharacterMap.ALPHA);
KeyEvent[] events = CharMap.getEvents(szRes);
for(int i=0; i<events.length; i++)
MainWebView.dispatchKeyEvent(events[i]); // MainWebView is webview
I'm still new to Java/Android, so my answer may not work out of the box, but you may still get the idea.
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
...
public class Sample {
...
public boolean convertStringToKeyCode(String text) {
KeyCharacterMap mKeyCharacterMap =
KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD);
KeyEvent[] events = mKeyCharacterMap.getEvents(text.toCharArray());
for (KeyEvent event2 : events) {
// We get key events for both UP and DOWN actions,
// so we may just need one.
if (event2.getAction() == 0) {
int keycode = event2.getKeyCode();
// Do some work
}
}
}
I got the idea when I was reading the code of sendText method in uiautomator framework source code:
Very rude solution but works for most characters.
Remember to do an uppercase if your text contains lowercase letters, you can add META_SHIFT_ON in that case if you then send a KeyEvent
for (int i = 0; i < text.length(); i++) {
final char ch = text.charAt(i);
try {
dispatch(KeyEvent.class.getField("KEYCODE_" + ch).getInt(null));
} catch (Exception e) {
Log.e(_TAG, "Unknown keycode for " + ch);
}
}
No, you cannot read a character "0" from the input and use a magical function to transform that to KeyEvent.KEYCODE_0 ... If you do, you will have to write a parser that switches on the read letter and return these values yourself.
For all I know, before reading the character you should've captured the thing in the onKey(). Depending on the number of keys you need to handle this way, a virtual android keyboard might be your only option, if this boilerplate code doesn't do the trick
switch(keyPress)
{
case '0': return KeyEvent.KEYCODE_0;
case '1': return ...
//...
case 'Z': return KeyEvent.KEYCODE_Z;
}

Format Android EditText to specific pattern

I need the user to enter text in an EditText according to this specfic pattern:
123.456-7890-123.456
The user can input any number of integers, so they could as well enter 123.456-7
I do not want the user to enter . or - just the numbers, like an input mask.
Also the numeric keyboard should only show.
I've searched StackOverflow extensively and have seen examples that use InputFilter, ChangedListener, TextWatcher but have not found anything simlar to what I'm trying to do. I've tried in various implementations of what I've found, but I'm inexperienced in using these so I may have overlooked something.
Any suggestions would be welcome.
You're going to have to use a TextWatcher and a regular expression pattern matcher to accomplish what you're trying to do.
This answer should be helpful: Android AutoCompleteTextView with Regular Expression?
You can create your own class that implements InputFilter. Then you would apply it as follows:
MyInputFilter filter = new MyInputFilter(...);
editText.setFilters(new InputFilter[]{filter});
Refer to the docs for how InputFilter is intended to work, then refer to the source code for some of the InputFilters used in Android for some ideas how to implement them.
After many failed attempts to implement InputFilter or Regular Expressions I opted for something a little more straight forward:
public void onTextChanged(CharSequence s, int start, int before, int count) {
String a = "";
String str = id.getText().toString();
String replaced = str.replaceAll(Pattern.quote("."),"");
replaced = replaced.replaceAll(Pattern.quote("-"),"");
char[] id_char = replaced.toCharArray();
int id_len = replaced.length();
for(int i = 0; i < id_len; i++) {
if(i == 2 || i == 12) {
a += id_char[i] + ".";
}
else if (i == 5 || i == 9) {
a += id_char[i] + "-";
}
else a += id_char[i];
}
id.removeTextChangedListener(this);
id.setText(a);
if(before > 0) id.setSelection(start);
else id.setSelection(a.length());
id.addTextChangedListener(this);
}
I don't know if this is the best approach but it does work. One problem I still haven't solved is how to handle cursor placement after the user deletes or inserts a number. If the user inserts the cursor somewhere in the EditText and enters a new number the cursor jumps to the end of the EditText. I would like the cursor to stay where it is at. Another problem if the user inserts the cursor within the EditText number and backspaces to delete a number, then the first key entry doesn't work and on the second key the number is entered. I can only guess this has to do with focus?
Use this: https://github.com/alobov/SimpleMaskWatcher.
Just set your mask for this watcher (###.###-####-###.###). It will add special symbols automatically and wont check your input string for being complete.
But showing the numeric keyboard you must handle by your own using android:inputType="number" tag for your EditText.

Categories

Resources