Building an Android Input Method (IME) for Emoji/Sticker Sending in WeChat
This article explains how to develop an Android input‑method service that displays a custom emoji keyboard, retrieves image paths, commits them to the active app, and uses AccessibilityService to automate sending, covering project setup, core APIs, XML keyboard layout, and advanced optimization techniques.
The article introduces a WeChat emoji‑sending solution that extracts the hidden image‑path feature of WeChat and implements it as a dedicated input‑method app, reducing the steps required for users to send stickers.
API Overview – The core class for any Android IME is InputMethodService , which manages lifecycle callbacks such as onCreate() , onCreateInputView() , onCreateCandidatesView() , onStartInputView(EditorInfo) , onFinishInput() and onDestroy() . Interaction with the target app is performed via the InputConnection obtained through getCurrentInputConnection() , offering methods like getTextBeforeCursor() , commitText() , deleteSurroundingText() , etc.
Keyboard Layout – A simple keyboard can be built using KeyboardView and Keyboard . The XML file defines rows and keys, their codes and visual attributes. Example snippet:
<?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"/>
...
</Row>
...
</Keyboard>In SoftInputService the method onCreateInputView() returns a configured KeyboardView :
@Override
public View onCreateInputView() {
mKeyboard = new Keyboard(getApplicationContext(), R.xml.qwerty);
mInputView = new KeyboardView(getApplicationContext(), null);
mInputView.setOnKeyboardActionListener(this);
mInputView.setKeyboard(mKeyboard);
return mInputView;
}When a key is pressed, KeyboardView determines the key via getKeyIndices(x, y) and forwards the character to InputMethodService , which finally calls InputConnection.commitText() to insert the text (or image path) into the focused app.
Project Setup – Create a service class extending InputMethodService (e.g., SoftInputService ) and a settings activity. Register the service in AndroidManifest.xml with the required permission android.permission.BIND_INPUT_METHOD and meta‑data pointing to an @xml/method file:
<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>The method XML declares the settings activity and whether the IME supports switching to the next input method.
Emoji/Sticker Functionality – The IME displays a GridView of emoji images. Clicking an item retrieves the local cache path of the image and commits it as text. WeChat automatically parses the path and shows a confirmation dialog; confirming sends the image (GIFs become animated stickers).
To obtain the search keyword entered before switching to the IME, the service reads the current text via InputConnection.getTextBeforeCursor() and then clears it with deleteSurroundingText() before fetching related emojis from external sources.
Advanced Optimization with AccessibilityService – Two AccessibilityService examples automate the confirmation click and the input‑method picker. The first listens for the WeChat confirmation button (text "确定") within 500 ms after an image path is committed and triggers performAction(ACTION_CLICK) . The second detects a long‑press event in WeChat, shows the input‑method picker, and automatically selects the custom IME named "Gifin".
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
CharSequence packageName = event.getPackageName();
AccessibilityNodeInfo root = getRootInActiveWindow();
if (root != null) {
if ("com.tencent.mm".equals(packageName.toString())) {
long currentTime = System.currentTimeMillis();
long commitTextTime = SharedPrefUtil.getLong(Constants.KEY_TIMESTAMP_ASSIST, 0);
if (currentTime - commitTextTime < 500) {
List
confirm = root.findAccessibilityNodeInfosByText("确定");
if (confirm != null && confirm.size() > 0) {
confirm.get(0).performAction(ACTION_CLICK);
}
}
}
root.recycle();
}
}These automations reduce the user workflow to three steps: enter a search term, select an emoji, and send it.
Conclusion – The guide provides a complete, open‑source example (GitHub: https://github.com/QiaoJianCheng/Gifin) for building an Android IME focused on emoji sending, covering basic lifecycle, UI construction, input‑connection handling, and optional accessibility‑based shortcuts, making it a practical learning resource for beginners interested in mobile input‑method development.
Sohu Tech Products
A knowledge-sharing platform for Sohu's technology products. As a leading Chinese internet brand with media, video, search, and gaming services and over 700 million users, Sohu continuously drives tech innovation and practice. We’ll share practical insights and tech news here.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.