InputConnection是IMF裡面一個重要的接口,他是實現BaseInputConnection和InputConnectionWrapper 上層的接口。主要用於應用程序和InputMethod之間通信的通道,包括實現讀取關標周圍的輸入,向文本框中輸入文本以及給應用程序發送各種按鍵事件。
- InputConnection ic = getCurrentInputConnection(); //獲取InputConnection接口
-
- if (ic != null){
- ic.beginBatchEdit(); //開始輸入編輯操作
- if (isShifted()) {
- text = text.toString().toUpperCase();
- }
- ic.commitText(text, 1); //將text字符輸入文本框,並且將關標移至字符做插入態
- ic.endBatchEdit(); //完成編輯輸入
- }
接口InputMethod是上節說到的AbstractInputMethodService和InputMethodService的上層接口,它可以產生各種按鍵事件和各種字符文本。
所有的IME客戶端都要綁定BIND_INPUT_METHOD,這是IMF出於對安全的角度的考量,對使用InputMethodService的一個所有客戶端的強制要求。否則系統會拒絕此客戶端使用InputMethod。
- <service android:name="IME"
- android:label="@string/SoftkeyIME"
- android:permission="android.permission.BIND_INPUT_METHOD">
在這個接口中有
bindInput(InputBinding binding) 綁定一個一個應用至輸入法;
createSession(InputMethod.SessionCallback callback) 創建一個新的InputMethodSession用於客戶端與輸入法的交互;
startInput(InputConnection inputConnection, EditorInfo info) 輸入法准備就緒開始接受各種事件並且將輸入的文本返回給應用程序;
unbindInput() 取消應用程序和輸入法的綁定;
showSoftInput(int flags, ResultReceiver resultReceiver) 和hideSoftInput(int flags, ResultReceiver resultReceiver) 顧名思義是顯示和隱藏軟鍵盤輸入。
InputMethodSession是一個可以安全暴露給應用程序使用的接口,他需要由InputMethodService和InputMethodSessionImpl 實現。
以下是一段在Framework中取到的代碼,可以比較全面的反應這個接口的使用:
final InputMethodSession mInputMethodSession;
public void executeMessage(Message msg) {
- switch (msg.what) {
- case DO_FINISH_INPUT:
- mInputMethodSession.finishInput(); //應用程序停止接收字符
- return;
- case DO_DISPLAY_COMPLETIONS:
- mInputMethodSession.displayCompletions((CompletionInfo[])msg.obj); //輸入法自動完成功能
- return;
- case DO_UPDATE_EXTRACTED_TEXT:
- mInputMethodSession.updateExtractedText(msg.arg1,
- (ExtractedText)msg.obj);
- return;
- case DO_DISPATCH_KEY_EVENT: {
- HandlerCaller.SomeArgs args = (HandlerCaller.SomeArgs)msg.obj;
- mInputMethodSession.dispatchKeyEvent(msg.arg1,
- (KeyEvent)args.arg1,
- new InputMethodEventCallbackWrapper(
- (IInputMethodCallback)args.arg2)); //處理按鍵
- mCaller.recycleArgs(args);
- return;
- }
- case DO_DISPATCH_TRACKBALL_EVENT: {
- HandlerCaller.SomeArgs args = (HandlerCaller.SomeArgs)msg.obj;
- mInputMethodSession.dispatchTrackballEvent(msg.arg1,
- (MotionEvent)args.arg1,
- new InputMethodEventCallbackWrapper(
- (IInputMethodCallback)args.arg2));
- mCaller.recycleArgs(args);
- return;
- }
- case DO_UPDATE_SELECTION: {
- HandlerCaller.SomeArgs args = (HandlerCaller.SomeArgs)msg.obj;
- mInputMethodSession.updateSelection(args.argi1, args.argi2,
- args.argi3, args.argi4, args.argi5, args.argi6); //更新選取的字符
- mCaller.recycleArgs(args);
- return;
- }
- case DO_UPDATE_CURSOR: {
- mInputMethodSession.updateCursor((Rect)msg.obj); //更新關標
- return;
- }
- case DO_APP_PRIVATE_COMMAND: {
- HandlerCaller.SomeArgs args = (HandlerCaller.SomeArgs)msg.obj;
- mInputMethodSession.appPrivateCommand((String)args.arg1,
- (Bundle)args.arg2); //處理應用程序發給輸入法的命令
- mCaller.recycleArgs(args);
- return;
- }
- case DO_TOGGLE_SOFT_INPUT: {
- mInputMethodSession.toggleSoftInput(msg.arg1, msg.arg2); //切換軟鍵盤
- return;
- }
- }
- Log.w(TAG, "Unhandled message code: " + msg.what);
- }