☝ click on the blue word above, follow us!
Words: 5191 words
Estimated reading time: 20 minutes
Directory:
1
Introduction;
2
Introduction and process of Android input method development;
3
Dou Map APP development introduction;
4
Dou Map APP function optimization;
5
Summary.
01
takeaway
There are many applications of wechat bucket map, but most of them are realized through wechat sharing. It is necessary to download the APP, download the expression and share it to the wechat contact person, and the operation steps are complicated. And based on the input method WeChat figure fights a lot less operation, now the input method available in the market have a bucket chart module, some patients with obsessive-compulsive disorder, however, to the input of a third party of the bucket figure design of the module is not satisfied, or steps still complex, bundled module, don’t like im have advertising, need to read the privacy information such as a variety of reasons, I just don’t want to use a third-party input method that I don’t like. Based on this demand, I can separate the bucket chart module and make an input method APP focusing on the bucket chart.
Through the analysis of the input method of has been on the market a pipe graph module can learn WeChat a hidden function, is similar to chat in the input box input/storage/emulated / 0 / Android/data/cache/al-qeada if image file path, WeChat automatically parse images, Click ok to send the picture directly. If it is a GIF, it will be directly converted into an expression. Therefore, we only need to search expressions through keywords in the input method panel to display the list of expressions, and directly click the picture path on the screen of expressions to realize automatic sending. Then the key problem lies in how to construct an input method project. Finally, in order to make operation more convenient, auxiliary functions can be used to improve user experience.
02
Input method development
1. Introduction of API
Simply put, to develop an input method, you only need to use a core class and a few optional auxiliary classes.
The core class is InputMethodService, an input method almost all functions are realized by it, including the construction of keyboard interface, keyboard language switch, pinyin Chinese conversion, candidate word display, text screen and other logic through this class to achieve. The InputMethodService class has the following main methods to manage the life cycle of the InputMethodService:
-
OnCreate (): set theme, create window, fill root view, set layout, etc. We can also do some initialization here, but don’t forget to call supper. OnCreate ();
-
OnCreateInputView (): Returns a view as an input method for the Keyboard layout. This view is usually generated by the KeyboardView and Keyboard helper classes, but it is also fully customizable. Switching an input method is called only once;
-
OnCreateCandidatesView (): Returns a view to display candidate words. This view is optional and overlays the top of the application, usually with a translucent background, but the market input method is usually used to display the pinyin part, and puts candidate words in the InputView. Similarly, switching an input method will only be called once;
-
onStartInputView(EditorInfo): It will be called every time the keyboard is invoked or the EditText is switched, and the EditorInfo of the EditText is passed in. The input method should be based on the information of the EditorInfo to determine Chinese and English, numbers, enter key types, etc., to display different keyboards. So dynamically switching the layout of the InputView;
-
OnFinishInput (): called when input ends. At this time, some reset operations can be performed, such as hiding CandidatesView, restoring InputView to the default layout, etc.
-
OnDestroy (): this function is called when another input method is switched. This function is also called when the actual input method does not take a while and the system temporarily kills the process.
Some students may have some doubts about what “InputView” and “CandidatesView” are on earth. The following picture can be clearly expressed:
And the life cycle defined by these methods can be deeply understood by an official figure of Android Developers[1]. I believe that every article related to input methods will have this classic figure:
In InputMethodService, responsible for working with the APP interaction is input is its holdings of InputConnection object, through getCurrentInputConnection () method to obtain, InputConnection has the following common methods:
-
GetTextBeforeCursor (n): Get n characters before the cursor;
-
GetTextAfterCursor (n): Gets n characters after the cursor;
-
GetSelectedText (): Gets the selected character;
-
DeleteSurroundingText (beforeLength, afterLength): Deletes characters before and after the cursor;
-
CommitText (text): Send text to the APP input box;
-
SendKeyEvent (keyEvent): Send special key code, such as enter, backspace, etc.
As mentioned above, InputView can be a KeyboardView. KeyboardView contains some general functions of the Keyboard. For example, the sending of special keys (enter, backspace, etc.), the function of sliding gestures, the function of long pressing the keyboard, the play of key sound, etc. The KeyboardView is just an empty view whose layout is not determined. Searching its code, we find that there is a member Keyboard, which is another auxiliary class. The main task of Keyboard is to carry specific Keyboard layout, such as Chinese and English Keyboard, numeric Keyboard, symbolic Keyboard, etc. Generally, such correspondence can be defined by an XML file (as shown in Figure 2.1.3). Load this XML file when constructing the Keyboard, so that the KeyboardView holds the reference of all the keys of the Keyboard. When a key is pressed, the KeyCode corresponding to the key is passed to the InputMethodService via the OnKeyboardActionListener set (remember, At this point KeyboardView is already an InputView held by InputMethodService), or it’s been processed — like processing pinyin to Chinese characters — and sent the processed text to InputMethodService, InputMethodService calls the commitText() method to screen text to the EditText of the current APP focus.
For the use of KeyboardView and Keyboard, Google official has a good example, interested students can download to study: SoftKeyboard Sample[2].
2. General input method development steps
Next, I will introduce the complete development and configuration of an input method. Of course, our wechat Doutu APP because it does not involve word processing and input, there are many fewer steps. After understanding the complete process, it is no problem to do doutu APP.
2.1 Creating projects and Configurations
There is no big difference between the input method application and the ordinary APP. Just create a new project as usual. However, to let the system know that this is an input method application, some configuration is needed.
Start by creating a new class SoftInputService that inherits from InputMethodService and leaves the content blank. Then create a new SettingsActivity for the input method Settings screen, again without writing the content. In the AndroidManifest, SoftInputService is configured as follows:
<service
android:name="com.package.InputService"
android:permission="android.permission.BIND_INPUT_METHOD">
<intent-filter>
<action android:name="android.view.InputMethod" />
</intent-filter>
<meta-data
android:name="android.view.im"
android:resource="@xml/method" />
</service>
Copy the code
The system detects android.view.InputMethod action indicating that the application is an InputMethod and checks whether the application has android.permission.BIND_INPUT_METHOD. @xml/method = @xml/method
<input-method xmlns:android="http://schemas.android.com/apk/res/android"
android:settingsActivity="com.package.SettingsActivity"
android:supportsSwitchingToNextInputMethod="true">
</input-method>
Copy the code
settingsActivity
SettingsActivity
supportsSwitchingToNextInputMethod
At this point, if packaged and installed, we can see our input method in the system Settings, but no actual functionality yet.
2.2 Keyboard layout and text on the screen
As mentioned earlier, you can use KeyboardView and Keyboard for simple Keyboard layouts, so SoftInputService onCreateInputView() returns a KeyboardView object, Set up Keyboard and Listener before returning:
@Override
public View onCreateInputView() {
mKeyboard = new Keyboard(getApplicationContext(), R.xml.qwerty);
mInputView = new KeyboardView(getApplicationContext(), null);
mInputView.setOnKeyboardActionListener(this);
mInputView.setKeyboard(mKeyboard);
return mInputView;
}
Copy the code
Keyboard carries the corresponding relationship between Keyboard keys and KeyCode, which is realized by filling XML files with constructors. The following is a complete XML mapping of QWERTY Keyboard:
<? The XML version = "1.0" encoding = "utf-8"? >
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
android:keyWidth="10%p"
android:horizontalGap="0px"
android:verticalGap="0px"
android:keyHeight="@dimen/key_height">
<Row>
<Key android:codes="113" android:keyLabel="q" android:keyEdgeFlags="left"/>
<Key android:codes="119" android:keyLabel="w"/>
<Key android:codes="101" android:keyLabel="e"/>
<Key android:codes="114" android:keyLabel="r"/>
<Key android:codes="116" android:keyLabel="t"/>
<Key android:codes="121" android:keyLabel="y"/>
<Key android:codes="117" android:keyLabel="u"/>
<Key android:codes="105" android:keyLabel="i"/>
<Key android:codes="111" android:keyLabel="o"/>
<Key android:codes="112" android:keyLabel="p" android:keyEdgeFlags="right"/>
</Row>
<Row>
<Key android:codes="97" android:keyLabel="a" android:horizontalGap="5%p" android:keyEdgeFlags="left"/>
<Key android:codes="115" android:keyLabel="s"/>
<Key android:codes="100" android:keyLabel="d"/>
<Key android:codes="102" android:keyLabel="f"/>
<Key android:codes="103" android:keyLabel="g"/>
<Key android:codes="104" android:keyLabel="h"/>
<Key android:codes="106" android:keyLabel="j"/>
<Key android:codes="107" android:keyLabel="k"/>
<Key android:codes="108" android:keyLabel="l" android:keyEdgeFlags="right"/>
</Row>
<Row>
<Key android:codes="-1" android:keyIcon="@drawable/sym_keyboard_shift"
android:keyWidth="15%p" android:isModifier="true"
android:isSticky="true" android:keyEdgeFlags="left"/>
<Key android:codes="122" android:keyLabel="z"/>
<Key android:codes="120" android:keyLabel="x"/>
<Key android:codes="99" android:keyLabel="c"/>
<Key android:codes="118" android:keyLabel="v"/>
<Key android:codes="98" android:keyLabel="b"/>
<Key android:codes="110" android:keyLabel="n"/>
<Key android:codes="109" android:keyLabel="m"/>
<Key android:codes="-5" android:keyIcon="@drawable/sym_keyboard_delete"
android:keyWidth="15%p" android:keyEdgeFlags="right"
android:isRepeatable="true"/>
</Row>
<Row android:rowEdgeFlags="bottom">
<Key android:codes="-3" android:keyIcon="@drawable/sym_keyboard_done"
android:keyWidth="15%p" android:keyEdgeFlags="left"/>
<Key android:codes="-2" android:keyLabel="123" android:keyWidth="10%p"/>
<Key android:codes="-101" android:keyIcon="@drawable/sym_keyboard_language_switch"
android:keyWidth="10%p"/>
<Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space"
android:keyWidth="30%p" android:isRepeatable="true"/>
< Key android: codes = "46, 44" android: keyLabel = ",,"
android:keyWidth="15%p"/>
<Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return"
android:keyWidth="20%p" android:keyEdgeFlags="right"/>
</Row>
</Keyboard>
Copy the code
Now that Keyboard is populated, call keyboardView.setKeyboard (Keyboard), pass Keyboard to KeyboardView, At this point, KeyboardView will collect the mapping relationship and location of all the keys of the Keyboard (it can be seen from the keyWidth and keyHeight attributes in the XML file that the position of each key has been fixed). When the key is clicked, KeyboardView calls the getKeyIndices(X, Y) method to calculate which key is clicked based on the location of the click on the screen. The OnKeyboardActionListener is set up to call back the output text to SoftInputService. SoftInputService received word can invoke InputConnection.com mitText (text) to text on the screen is the input of the APP. At this point, an input method with the simplest function of inputting English, numbers and symbols has been completed.
2.3 Implementation of complex function input method
Of course, any input method APP on the market will not be so simple, but we know the principle, complex functions can be implemented one by one.
We can call setCandidatesViewShown(show) method in SoftInputService to dynamically show and hide the floating view. The content is completely customizable, usually showing a list of words or words that are expected to be typed.
As for how to turn pinyin into possible Chinese characters, this requires the help of some thesaurus to achieve, each major input method has its own thesaurus, and even has its own cloud thesaurus, uploaded to the network when input, can match some network catchwords and so on. These operations can be wrapped in KeyboardView or implemented in a separate computing module.
The common 26-key keyboard and nine-grid keyboard can be dynamically implemented by modifying the KeyboardView. Regardless of the layout, the final text is computed and processed, rather than simply placed in XML. Due to the limitations of KeyboardView functions and simple appearance, mature input methods are almost their own definition of InputView rather than using a simple KeyboardView.
03
Wechat Doutu APP
We already know that by inputting a picture path in the input box of wechat, we can directly send the picture. So the key of Doutu APP is to obtain a list of expressions, which is displayed in the keyboard layout. When clicking the picture expression, the local cache path of the picture is presented as a text commit.
For expression sources, we can grab expressions from the existing major websites, such as Sogou expression, Doutu la, Doutu Terminator and other websites, all of which have a large number of expression resources. Through the check function or capture operation of Google Chrome, we can know the interface to search expressions by keywords. Thus it is very easy to obtain the resources of these websites (only for learning and communication, do not commercial or malicious crawl).
Image display, we can use a simple GridView to show how to obtain the image local cache path, you can query the mainstream image loading framework (Glide, Fresco, etc.) API.
The next problem we’ll find is how to pass in the emoticon search keywords. Because our APP itself is an input method, it is impossible to switch to another input method to input text within the input method, and our own input method does not support input text (it is quite complicated to input Chinese characters, so we will focus on the graph).
There are many workarounds to realize this problem. First, you can start an Activity in the input method, call the normal input method input text in the Activity, switch back to the input graph input method and call back the input text when closed. The problem of this method is that the input method application allows switching to other input methods. However, it is not allowed to switch back to its own input method, even if its own input method exists in the Service, is invalid. Although this can be done with the help of assistive functions, switching back and forth between input methods does not perform well visually.
Another method is to input the word that you want to search in the wechat input box, and then call up the input method to read the word that has been entered. Im reading focus on the input box is allowed, the call is above mentioned InputConnection. GetTextBeforeCursor (n), to search words can go after each expression sites related expressions and show, At this point we can call the InputConnection. DeleteSurroundingText () to delete the search words in the input box, because we no longer need it, and to avoid manually delete to enhance the user experience.
We can set the GridView OnItemClickListener or custom listening to and fro the click on the corresponding image path expression, and then call InputConnection.com mitText input to WeChat (text) method, At this point, wechat will automatically parse and pop up a confirmation dialog box (FIG. 3.1). Click “Send” to send the picture, and the GIF picture will automatically parse into a dynamic wechat expression to send.
04
Bucket chart function optimization
The above results can basically make you invincible in the process of fighting, but for the pursuit of the ultimate experience of the students, there is still to be optimized, the following two points can be optimized, all need to use the auxiliary function of the service.
First question, wechat pop-up dialog box, also need to click confirm, this step, how to click the expression immediately send, at this time we thought of AccessibilityService, through which can achieve automatic click. Since AccessibilityService is not the focus of today, how to use the specific students can Google, the following put on the AccessibilityService implementation part of the code:
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
CharSequence packageName = event.getPackageName();
AccessibilityNodeInfo root = getRootInActiveWindow();
if (root ! = null) {
If (" com.tceh.mm ".equals(packageName. ToString ())) {// wechat packageName
long currentTime = System.currentTimeMillis(); // Get the current time
long commitTextTime = SharedPrefUtil.getLong
(Constants.KEY_TIMESTAMP_ASSIST, 0); // Get the image path submission time
If (currentTime-committextTime < 500) {// The image path is triggered within 500ms
List<AccessibilityNodeInfo> confirm =
Root. FindAccessibilityNodeInfosByText (" ok "); // Find the confirm button
if (confirm ! = null && confirm.size() > 0) {
confirm.get(0).performAction(ACTION_CLICK); // Trigger the click event
}
}
}
root.recycle();
}
}
Copy the code
AccessibilityService
The second question is, after entering the search term in the input box of wechat, we have to pull down the notification bar, click “Select input method” in the notification bar, and then click the input method selector that pops up to complete the input method switch. It requires at least one slide and two clicks in three steps. Can we complete the input method switch in one step? Of course can. AccessibilityService is also used to implement:
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
CharSequence packageName = event.getPackageName();
if ("com.tencent.mm".equals(packageName.toString())) {
if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_LONG_CLICKED) {
InputMethodManager inputMethodManager = (InputMethodManager)
App.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
if (inputMethodManager ! = null) {
inputMethodManager.showInputMethodPicker();
}
}
}
AccessibilityNodeInfo root = getRootInActiveWindow();
if (root ! = null) {
if ("android".equals(packageName.toString())) {
List<AccessibilityNodeInfo> infos = root.findAccessibilityNodeInfosByText("Gifin");
if (infos ! = null && infos.size() > 0) {
infos.get(0).getParent().performAction(ACTION_CLICK);
}
}
root.recycle();
}
}
Copy the code
AccessibilityService
Other functions are free to use, such as adding search history, using multiple sources, adding favorites, saving to local and so on.
05
conclusion
To here, we can say “I never lose” dou figure, it is also not brag, dou figure on market at present is the fastest the most convenient is im kind of APP, and experienced a input method, found to implement a full figure process, also need to be at least 5 step operation, now we only need to enter a search term, search and display, click send three steps can be completed.
Of course, for many students, graph is not the goal, but learning technology is the focus. Although There are a lot of articles related to input method on Google, not many can be combined with the actual experience. Maybe the technical content of this APP is not high in the eyes of some masters, but for beginners, It is possible to find a more acceptable Angle and approach among many tutorials, and that is the point of this article. Learn the input method related knowledge again strongly recommended Google official example SoftKeyboard Sample.
Finally, while knowledge is long, life is short, if there is any mistake also hope readers comment, has open to making this APP source code (https://github.com/QiaoJianCheng/Gifin), also illustrates some pits at the same time, welcome anyone interested in to Star.
Reference:
[1].Android Developers(https://developer.android.com/guide/topics/text/creating-input-method.html)
[2].SoftKeyboard Sample(https://android.googlesource.com/platform/development/+/refs/heads/master/samples/SoftKeyboard/)
Maybe you’d like to see more
| sohu news recommendation algorithm is presented to you, are you care about
CTR prediction model of news recommendation system
The evolution of Internet architecture
The application of Embedding model in recommendation system
In-depth understanding of Flutter multithreading
Join sohu technology author day group
Thousand yuan payment waiting for you!
Stamp here! ☛