Handling dead keys in Android KCM - android

I'm using library Extra Physical Keyboard Layouts which is able to add new keyboard layouts to the device. Don't confuse it with whole new keyboards like SwiftKey, Samsung Keyboard etc.
This library is using KCM files which is Android standard for keyboard layout files.
I have my custom layout (originally KLC file) which I converted to KCM.
But these two main things about dead key are missing:
\u030c (ˇ) + \u0075 (u) should produce \u016f (ů), but now it is producing \u01d4 (ǔ)
But for example:
\u030c (ˇ) + \u0074 (t) result \u0165 (ť) is fine
\u030c (ˇ) + \u030c (ˇ) should produce \u003d (=).
Basically double pressing key EQUALS should produce \u003d (=)
The problem is that afaik there is no way how to handle dead keys in KCM file and are handled automatically by the OS.
Is there a way how to solve mentioned problems in KCM file or any other way without creating custom keyboard like SwiftKey etc.?
Mentioned KLC and KCM files can be found here.
Thank you

Related

Register hardware keyboard shortcuts in Android's help menu

Android supports external hardware keyboards as input, which may send keyboard shortcuts (e.g. Ctrl+A) in which there are some ways to program my app to accept shortcuts from external keyboards (e.g. like this: Custom keyboard shortcuts).
I came across this keyboard shortcut "help" screen in Android (activated by pressing OS + /) (see picture below)
and noticed some apps have some keyboard shortcuts directly registered within the system shortcuts help screen(these screens are not provided by the app, they can be found by pressing OS + /).
So far, the apps that I see that have this feature are:
Samsung Internet
Samsung One UI Home
Google Chrome
Chromium-based browsers (e.g. Brave)
Google Docs, Sheets, Slides
I cannot find any way to register my keyboard shortcuts in my app programmatically such that they will be recognised by the system. How can I possibly implement it in my app?
I do know iOS/iPadOS has such a feature.
Perhaps Android does have such a feature too? It seems like it would be quite useful to app developers and users, not sure why it's not documented at all in Android Developer documentation.
Thanks.
This feature is not documented in the Android Developer website, so I had to search around.
Since it is supported by AOSP, this is not a proprietary method/function by Google. No root is required on your users' devices.
Since this feature is available in Chromium-based browsers, I decided to check up the open-source Chromium Android source code (a mirror on GitHub is available here by someone: https://github.com/kuoruan/Chromium-Android) and I have discovered how this feature is implemented.
The relevant lines are here:
https://github.com/kuoruan/Chromium-Android/blob/29ba2966ff145c9cb2492a971f9c03f879c5b9c9/app/src/main/java/org/chromium/chrome/browser/KeyboardShortcuts.java#L117
https://github.com/kuoruan/Chromium-Android/blob/29ba2966ff145c9cb2492a971f9c03f879c5b9c9/app/src/main/java/org/chromium/chrome/browser/ChromeTabbedActivity.java#L2135
In any Activity, you can override the method onProvideKeyboardShortcuts.It provides 3 parameters: data, menu, and deviceId, in which we only need data here.
Here is the method signature:
fun onProvideKeyboardShortcuts(
data: MutableList<KeyboardShortcutGroup>?,
menu: Menu?,
deviceId: Int
)
This only works on API 24 (Android Nougat) and above.
data is a mutable list of KeyboardShortcutGroup, which is a group of keyboard shortcuts.
So, you can have multiple groups containing multiple shortcuts, useful for grouping the shortcuts for your users.
To register your shortcuts,
Create a KeyboardShortcutGroup. This is required to store and group your keyboard shortcuts together. The class accepts a CharSequence as a parameter for the name of the group, so you have to use getString(R.string.your_resource) for string resources.
val keyboardShortcutGroup = KeyboardShortcutGroup(/* the name of your group here: */ "Test Group")
Define your keyboard shortcuts. Keyboard shortcuts are defined using KeyboardShortcutInfo objects, which accepts 3 parameters in it's constructor - a label, the key(e.g. A/ Z/ 8/ 9), and the modifier key. A single keyboard shortcut is created this way:
KeyboardShortcutInfo("Shortcut One" /*label*/, KeyEvent.KEYCODE_Z/*key*/, KeyEvent.META_ALT_ON/*modifier*/)
You need to pass in key codes into the constructor for the key and the modifier key.
The key and modifier key must be passed in seperately.
Here are the list of available key codes:
https://developer.android.com/reference/android/view/KeyEvent#KEYCODE_0 (See those prefixed with KEYCODE)
Based on testing, the modifier keys which work are:
Ctrl META_CTRL_ON
Alt META_ALT_ON
Shift META_SHIFT_ON
Super/OS/Meta (see https://android.stackexchange.com/a/243218/307843) META_META_ON
Function META_FUNCTION_ON
Left/Right keys for all of these are also available(i.e. META_ALT_LEFT_ON)
META_SYM_ON may work(have not tested yet), but Caps Lock doesn't work.
To combine modifier keys,
in Java, use the bitwise operator:
KeyEvent.META_ALT_LEFT_ON | KeyEvent.META_CTRL_ON
in Kotlin, use the or operator:
KeyEvent.META_ALT_LEFT_ON or KeyEvent.META_CTRL_ON
To this KeyboardShortcutGroup, add shortcuts using addItem.
keyboardShortcutGroup.addItem(shortcut /* <-- the shortcut created earlier */)
Add your KeyboardShortcutGroup to data
data.add(keyboardShortcutGroup)
Your code should look like this:
override fun onProvideKeyboardShortcuts(
data: MutableList<KeyboardShortcutGroup>?,
menu: Menu?,
deviceId: Int
) {
super.onProvideKeyboardShortcuts(data, menu, deviceId)
// Requires API 24
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
val keyboardShortcutGroup = KeyboardShortcutGroup("Test Group")
keyboardShortcutGroup.addItem(KeyboardShortcutInfo("Shortcut One", KeyEvent.KEYCODE_Z, KeyEvent.META_ALT_ON))
data?.add(keyboardShortcutGroup)
}
}
You should see the end result:
You can use this to inform users of available shortcuts. Note that this does not implement them, it merely adds a listing to the Android shortcut menu.

Issue with float.Parse in Unity Android App

I develop an Android app. If I call
float.Parse("51.552058")
in Editor or App on my Mac Book (Language Setting English), it works fine. After publishing to Android (Language Setting German) the result of the Parse operation is not "51.552058" anymore but "5,155211E+09". I understand that this might be related to the device's language but I still don't really understand what is happening and why.
I also tried following with no success:
float.Parse("51.552058", System.Globalization.NumberStyles.Any)
float.Parse("51.552058", System.Globalization.NumberStyles.AllowDecimalPoint)
Did anyone stumble over this before?
float.Parse is culture dependent.
See e.g. from NumberFormatInfo
// '1,034,562.91' --> 1034562.91 (en-US)
// '1,034,562.91': FormatException (fr-FR)
// '1,034,562.91' --> 1034562.91 (Invariant)
Reason here is that in EU cultures the , is usually the decimal separator while the . is used as the group separator. So from the example above the correct format for fr-FR would be 1.034.562,91
You probably rather want to use CultureInfo.InvariantCulture like
float.Parse("51.552058", CultureInfo.InvariantCulture);
or directly NumberFormatInfo.InvariantInfo
float.Parse("51.552058", NumberFormatInfo.InvariantInfo);
which simply has defined
NumberDecimalSeparator .
NumberGroupSeparator ,

How to catch the key values from a custom keyboard on Android mobiles or tablets? How to make work an Android Keyboard & Barcode Scanner within Odoo?

I am trying to use Odoo with the application Barcode & QR code Keyboard, from Nikola Antonov (just an example, I do not know if there are better options), in order to read barcodes for the pickings.
The first problem I had to face was I had to show the keyboard in this picking view
So I needed to create an input field in order to click in it and show the Android Keyboard, or in this case the Nikola Antonov keyboard. Then, I had to assign the function handler to this input text field:
this.$('#input_text_barcodes').on('keyup', self.getParent().barcode_scanner.handler);
The function is only working as expected if I use the normal Android Keyboard (AOSP) and only with numbers. The letters of the Android Keyboard or whatever character of the Nikola Antonov Keyboard are not working (only the backspace)
this.handler = function(e){
self.$('#aux_label').text('>> CODE: ' + e.which)
self.$('#aux_label').text('>> KEY CODE: ' + e.keyCode)
self.$('#aux_label').text('>> KEY: ' + e.key)
// [...]
I tried switching the languages of the keyboard as well, but with the same result
Should I change the keyup event?
Is there other way to catch the characters?
Finally I have asked to the developer of the application directly and he solved the problem quite fast. He made it work with numeric keys, that is enough for what I wanted to achieve.

JavaFxPorts TextField Issue - Android Keyboard wont function

I developed a simple javafx application to be ported in Android Environment, however I cant type any characters in the TextField. I guess its a bug, how to fix this one?
Th problem on galaxy S5 android 5.0.1 is not present but on galaxy tab 4 android 5.0.2 it doesn't work i type but none is displyed.
Tried with normal textfield. And the problem persist also I have added the properties .
Another strange rhig is that the space where recognizer. And the del button . The text not
THe code by example is very easy
Rectangle2D visualBounds = Screen.getPrimary().getVisualBounds();
double width = visualBounds.getWidth();
double height = visualBounds.getHeight();
TextField tt= new TextField();
tt.setTranslateY(-150);
StackPane stackPane = new StackPane();
stackPane.getChildren().addAll(tt);
borderpane.setCenter(stackPane);
Scene scene = new Scene(borderpane, width, height);
stage.setScene(scene);
Assuming that CustomTextField is just a custom TextField, this is a known issue, not related to the CustomTextField itself, given that it works in other device.
If you debug it:
./adb logcat -v threadtime
you surely find an exception that explains the issue: a StackOverFlow exception.
On older devices it can be solved adding this: create a java.custom.properties file, and include in it this property:
monocle.stackSize=128000
You may also include this one:
monocle.platform=Android
(it will be soon included by default in the next version)
Put the file at the root of your classpath, e.g. in the folder src/android/resources of your project.
Build and deploy the project on your mobile and check again.

Can't get meta state from Android KeyEvent

Looks silly, but I can't get meta state out of KeyEvent, accessed from onKeyListener. Tried with all keyboards I have and with emulators.
Whether or not Shift, Ctrl, etc keys are pressed, keyEvent.getMetaState() returns 0. May it works for TextListener, but I don't need it for entering text, I just want to differentiate between Tab and Shift+Tab.
Thanks for anticipated help.
Update. What I just figured out is that meta state is reported for alphabetic keys, but not for other keys.
For example if I press left Shift+T the system generates KeyEvent for KEYCODE_SHIFT_LEFT and KEYCODE_T, and KeyEvent for KEYCODE_T has META_SHIFT_ON set. You can trick the system with Shift+TAB+T, in which case META_SHIFT_ON is set for both KEYCODE_T and KEYCODE_TAB. However with Shift+TAB the KeyEvent for KEYCODE_SHIFT_LEFT is not generated, and the meta state remains unaffected.
Maybe system keyboard configuration files need to be updated to allow combinations like Shift+TAB?
Yes, it's really about android configuration file.
You modify TAB entry in /system/usr/kychars/Generic.kcm (or the file for corresponding vendor) and add a line for shift, as the following:
key TAB {
label: '\t'
base: '\t'
shift: '\t'
ctrl, alt, meta: none
}
Some devices uses qwerty.kcm, which has the shift line alaready present. They should work OK without intrusion. BTW, unicode has provides a special code \u21B9 for Shift+TAB, but it might not be recognised by Android.

Categories

Resources