原创文章,转载请标注出处----
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); }