How does an Android app load a keyboard? - android

I need to bring up a few different keyboards: a 'standard' keyboard with Ctrl and Alt keys; maybe a cursor pad; and so on.
I have found the Keyboard class, which would let me define a keyboard in an XML resource. I have found that the KeyboardView class has a setKeyboard method ... and, so far, I have not found any other class that takes a Keyboard instance.
How am I supposed to use the KeyboardView? I tried adding one to my activity's XML; finding it at runtime with findViewById; and then calling setKeyboard ... but all this did was mess up my layout and not bring up the special keyboard.

This turns out to be very doable, and my initial problems probably had more to do with general Android newbiness (this is my first Android app) and not the KeyboardView. In particular, I'm used to visibility being a simple binary property.
Anyhow:
Declare the KeyboardView in your XML file with android:visibility="gone".
Before you make the view visible, call setKeyboard() to attach a keyboard. This is important, as the KeyboardView gets its size from the keyboard.
To get raw key events, call KeyboardView.setOnKeyboardActionListener(). After refactoring this functionality from a Dialog back to my main View, I put the OnKeyboardActionListener functionality in a stand-alone class, but this is not necessary.
I call keyboardView.setEnabled(true);. This does not seem to be necessary, but I am not sure (yet) under what circumstances it would matter; perhaps only if you call setEnabled(false).
I call keyboardView.setPreviewEnabled(true); - this is especially useful if the user won't be getting visual feedback from an input biox right above the keyboard.
Then, with the keyboard all set, call keyboardView.setVisibility(VISIBLE);.
To hide the keyboard when appropriate, just call keyboardView.setVisibility(GONE);. To change the keyboard (as on a shift key, or a cycle-through-the-symbol-keyboards key, just call setKeyboard again. I use a Map<<Integer, Keyboard> to implement a lazy-create pattern; a weak reference may be desirable, if the program will run for a long time and the keyboard will not be used much.

Keyboard and KeyboardView are for making alternative input method engines (IME). These are then able to be chosen by the user, just as they can install Swype, Graffiti, and other ones from the Android Market.
You, as a developer, can create such an IME, but you cannot force it upon the user.

using the inputType attribute in your editText view will help pick between the different system keyboards (phone, email, etc) Also the APIDemos application that comes with the SDK has an example of how to implement a forced custom keyboard for your app only.

Related

UI Automator with custom keyboard. Find exact keyboard button and click it

I'm trying to write UI automation tests for the custom soft keyboard using UI Automator and\or Espresso. Tried different ways but I can't find a proper solution to "find the exact button on the opened keyboard and click it".
Problems:
UIAtomator's UiDevice.findObject(By.text("Q")).click() doesn't find Q button on keyboard.
Espresso's onView(withText("Q")).perform(click()) doesn't find the button either.
For now, it looks like the only way to click button is to measure XY coordinates based on screen height and keyboard height. But this solution is ugly and not persistent.
typeText("text")and uiObject.text = "text" don't work since it bypasses keyboard input.
Was anyone working with custom keyboards? Please help.
Since you're building a custom soft keyboard then I expect you're using a KeyboardView. KeyboardView draws the keys using a canvas therefore it is not possible to get the resource ids of the keys... so no chance to find them through the UiDevice's findObject method.
Considering the KeyboardView class is deprecated since API 29, a possible solution will be to reimplement your own KeyboardView (as suggested here) and use AccessibilityNodeInfo class to build virtual elements (one for each key) that will be included into the view hierarchy.
The best solution in my opinion would be to create your own TCP server to solve this issue. Please refer to this link to find out how: https://ops.tips/blog/a-tcp-server-in-c/

qt/qml android virtual keyboard z pozition

I met the trouble with which I cant deal. I need to place the qml component (for example the Rectangle) above the native android soft keyboard. Is it real to do so?
I think you can't change z of keyboard, because keyboard and your application are different apps, but you can disable it. Because lack of code in your question, I can guess that you have TextFiled, you can set it to readonly property.
Also you can check state of the keyboard and hide it, when it shows, but I'd not recommended this method

Creating an application specific keyboard

I want to create a custom keyboard which will be available in my application only (It's used jut for a single EditText in one activity), and I was wondering what would be the best way to do so. Here are my specifications for the keyboard:
It should always be displayed in the activity it is used (Regardless whether the EditText is focused or not).
It will have 2 or more keys layouts (Similar to the regular keyboard which has letters layout and a few numbers/symbols layouts).
Some keys may require some special action (Rather than simply adding their android:codes key value to the EditText).
It doesn't offer candidates for completion/correction.
It doesn't offer more than one input type (Like the regular keyboard which has TYPE_CLASS_NUMBER, TYPE_CLASS_DATETIME and so on...).
How should I develop it? Should I create a full input method service for it? Or should I create just a KeyboardView and add it to the activity's layout? (I want to use KeyboardView for the convenience of keys creation and click events handling)
Since it's a one-off thing and not meant as a separate app, You can simply use whatever method is easiest for you (The KeyboardView method).
Try it out and make sure it's responsive and snappy. If it works, then simple and easy method would be my recommendation.
Maybe you could take a look at this. I think the best way is to make a custom layout and inflate it. Theres a tutorial given here too.

"adjustResize" Android

I have an app that runs fullscreen by using:
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
Because of this the layout, android:windowSoftInputMode="adjustResize" is not working properly, i.e. it dose not resize.
Is there any way to get over the problem?
FYI: This is an existing AOSP (Android Open Source Project) bug: http://code.google.com/p/android/issues/detail?id=5497
Ideally this bug would be fixed, but until then here are a couple thoughts of how it could be worked around. Since I have no idea what application scenario this pertains to, these may not be very applicable.
In agreement with my best interpretation of the previous answer, design your layout so that adjustPan works ok with it. The first thing I can think of here is not having any headers or footers that are intended to remain on screen when the keyboard is up.
Don't use FLAG_FULLSCREEN with a layout that can accept text input. Possibly it wouldn't be a big deal to show the status bar when accepting input. However, for something that views content with embedded input fields (like a web browser) that has a fullscreen mode, this doesn't make much sense at all.
Implement adjustResize-like behavior of your own. I'm not sure how well this would work, but possibly you could write a subclass of whichever class is causing the keyboard to be shown (ex: EditText) where you either track when the keyboard is shown or take over the calls to show and hide the keyboard (overriding at least onKeyUp and onTouchEvent). When shown, resize your content - possibly with a best guess of the softinput height, since users can install different soft input methods. I believe this would be technically difficult and not reasonable to attempt without extreme need.
Instead of android:windowSoftInputMode="adjustResize" you can try with android:windowSoftInputMode="adjustPan"

View-specific IME?

I have a custom view for which I want the user to be able to enter characters from an app-defined set of characters. To do this, as I understand it, I need to write an input method service. The user not only needs to install it, but then needs to enable the IME in the Settings > Language & keyboard, and then select the custom IME for use in the view.
This seems really crazy. I want this IME to be used for just one view in one application. I don't want it to be available system-wide or force the user to make global setting changes.
The only alternative I can see is defining my own in-app custom view and simulate an IME (probably a full-screen one) when the view gains focus. Isn't there anything better?
I do not think the IMEs are conceived for that kind of task. Their concept is to allow user input in a standardized way so it can be used across multiple applications from different vendors.
My strategy would be similar to what you are thinking:
prevent the soft keyboard from appearing,
intercept the menu button key press to show your own instead,
add a custom layout (probably a GridView or a TableView inside a RelativeLayout with bottom gravity)
use an OnItemClickListener
send the required KeyEvents to the root View. If the characters are invented, the KeyCodes do not even need to relate to the ASCII character. You just intercept the code and use at will.
Sorry I can't give you an option as you asked, but this alternative does not seem to be much more work than creating a whole new IME.
Edit: upon reading the related question, it makes sense to use android.inputmethodservice.KeyboardView instead of reinventing the wheel with the GridView.

Categories

Resources