android4.4 framework层怎样阻止弹出软键盘(搜狗输入法软键盘放大)?

Android输入法框的梳理
/frameworks/base/services/java/InputMethodManagerService.java
这是整个系统当中,一切与输入法有关的地方的总控制中心。它通过管理下面三个模块来实现系统的输入法框架。
1、/frameworks/base/services/java/WindowManagerService
负责显示输入法,接收用户事件。
2、/frameworks/base/core/java/android.inputmethodservice/InputMethodService
输入法内部逻辑,键盘布局,选词等,最终把选出的字符通过commitText提交出来。要做一个像搜狗输入法这样的东西的话,主要就是在这里做文章。
3、InputManager
由UI控件(View,TextView,EditText等)调用,用来操作输入法。比如,打开,关闭,切换输入法等。
下面说一下InputMethodManagerService这个控制中心是怎么样与三个模块交互的。
1、与WindowManagerSerivce的交互。
首先,InputMethodManagerService在初始化时,会调用IWindowManager.Stub.asInterface(ServiceManager.getService(Context.WINDOW_SERVICE)),得到IWindowManager这个代理,然后通过IWindowManager与WindowManagerService交互。比如下面这些操作:
调用mIWindowManager.addWindowToken(mCurToken, WindowManager.LayoutParams.TYPE_INPUT_METHOD),让WindowManagerService显示输入法界面。
调用mIWindowManager.removeWindowToken(mCurToken)让输入法界面关闭。
调用mIWindowManager.inputMethodClientHasFocus(client)判断输入法是否聚焦。
2、与InputMethodService的交互。
InputMethodManagerService在内部维护着一个ArrayList&InputMethodInfo& mMethodList。这个列表会在服务启动时通过PackageManager查询当前系统中的输入法程序来得到。与之对应的,每一个输入法程序的AndroidManifest.xml中都会有一个Service,而每个Service中都会有标记来告诉系统,自己是个输入法程序。下面这个是我从系统自带的例子Samples/SoftKeyboard/AndroidManifest.xml中的取出来的:
&manifest xmlns:android=&/apk/res/android&&
&& & & &package=&com.example.android.softkeyboard&&
&& &&application android:label=&@string/ime_name&&
&& & & &&service android:name=&SoftKeyboard&
&& & & & & & & &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&
&& &&/application&
&/manifest&
另外,InputMethodManagerService内部还有一个PackageReceiver,当系统中有程序的安装、删除、重启等事件发生时,会更新mMethodList。InputMethodManagerService打开,关闭,切换输入法时,其实就是在操作mMethodList中某个InputMethodInfo。把InputMethodInfo中的代表某个输入法的InputMethodService启动或者销毁,就实现了输入法的打开和关闭。
3、与InputMethodManager的交互
InputMethodManager中会包含一个IInputMethodManager,这个东西就是InputMethodManagerService的代理,打开关闭输入法这些操作就是由InputMethodManager中的某些方法调用IInputMethodManager中相应的方法来实现的。比如:
mService.getInputMethodList()获取输入法列表。
mService.updateStatusIcon(imeToken, packageName, iconId)更新输入法图标,即屏幕上方状态栏中的输入法图标。
mService.finishInput(mClient)隐藏当前输入法。这所以不说关闭输入法,是因为输入法服务启动起来以后,只有在系统关闭或者切换输入法时才会关闭。
mService.showSoftInput(mClient, flags, resultReceiver)打开当前输入法。
分别介绍完三大模块之后,再介绍两个东西,输入法的实现和怎么样调用输入法。
1、以系统的SoftKeyboard为例,实现一个输入法至少需要Keyboard,KeyboardView,CandidateView,SoftKeyboard这四个东西。
CandidateView负责显示软键盘上面的那个候选区域。
Keyboard负责解析并保存键盘布局,并提供选词算法,供程序运行当中使用。其中键盘布局是以XML文件存放在资源当中的。比如我们在汉字输入法下,按下b、a两个字母。Keyboard就负责把这两个字母变成爸、把、巴等显示在CandidateView上。
KeyboardView负责显示,就是我们看到的按键。
上面这两人东西合起来,组成了InputView,就是我们看到的软键盘。
SoftKeyboard继承了InputMethodService,启动一个输入法,其实就是启动一个InputMethodService,当SoftKeyboard输入法被使用时,启动就会启动SoftKeyboard这个Service。InputMethodService中管理着一个继承自Dialog的SoftInputWindow,而SoftInputWindow里面就包括了InputView和CandidateView这两个东西。
2、怎么样调用输入法呢?
说起这个东西,很自然地想起EditText来,我们团队跟踪过这个Widget,EditText本身很简单,主要的代码在TextView和View当中。这两个Widget本身又很复杂,杂在一起说不清楚。这里我就把我们团队以前做过的一个小例子拿进来做参考,说明一下如何从一个View上调用输入法和如何接收输入法传过来的字符串。
小例子的起源来自于我们要做一个浏览器,需要在SurfaceView来在Canvas上面绘制自己需要的东西,开启自己的主控制循环线程,事件处理等。比如我要在SurfaceView上绘制输入浏览器中的按钮、文本、图片、输入框等,当然这些和ImageView,TextView没有关系,都是用自己的UI引擎来做的。最后所有问题都解决了,却在输入框上卡壳了。因为要实现输入,得调用EditText,否则就必须自己去和EditText一样连接输入法。以前找过相关资料,看网上也有人碰到过这个问题,但都没有答案。最后,还是团队中一个很牛的娃给解决了。代码很简单,不出二十行,但没资料,View的源码又太庞大,费的劲却是只有我们团队的人才能体会得到的。。。这里佩服张老二同学一下,没有他的努力,就没有下面这二十多行很重要很重要的源码的诞生。
首先,定义一个继承自BaseInputConnection的类。
public class MyBaseInputConnection extends BaseInputConnection{
public MyBaseInputConnection(View targetView, boolean fullEditor) {
super(targetView, fullEditor);
public static String tx=&&;
public boolean commitText(CharSequence text, int newCursorPosition) {//输入法程序就是通过调用这个方法把最终结果输出来的。
tx = text.toString();
BaseInputConnection相当于一个InputMethodService和View之间的一个通道。每当InputMethodService产生一个结果时,都会调用BaseInputConnection的commitText方法,把结果传递出来。
public class MyView extends SurfaceView ...{
InputMethodManager input = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);//得到InputMethodManager。
ResultReceiver receiver = new ResultReceiver(new Handler() {//定义事件处理器。
public void handleMessage(Message msg) {
input.showSoftInput(this, 0, mRR);//在你想呼出输入法的时候,调用这一句。
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {//这个方法继承自View。把自定义的BaseInputConnection通道传递给InputMethodService。
return new MyBaseInputConnection(this, false);
InputMethodManager: 整个输入法框架(IMF)结构的核心API,处理应用程序和当前输入法的交互。可以通过Context.getSystemService()来获取一个InputMethodManager的实例。
结构概览: 一个IMF结构中包含三个主要的部分: input method manager:管理各部分的交互。它是一个客户端API,存在于各个应用程序的context中,用来沟通管理所有进程间交互的全局系统服务。 input method(IME):实现一个允许用户生成文本的独立交互模块。系统绑定一个当前的输入法。使其创建和生成,决定输入法何时隐藏或者显示它的UI。同一时间只能有一个IME运行。 client application:通过输入法管理器控制输入焦点和IME的状态。一次只能有一个客户端使用IME。
applications: 大多数情况下,使用标准的TextView或者它的子类的应用很少能很好的使用soft input methods。你需要主要的主要事情如下: 当你的可编辑区域显示的时候,正确设置inputType,以便于input method能找到足够的context,这样input method才能更好的输入文本。 正确处理输入法显示的时候覆盖的区域。理想情况下,应用应该处理窗口缩小带来的影响。但是这依赖系统在需要的情况下对窗口重置的操作。你应该在activity中设置windowSoftInputMode属性或者在创建的窗口设置适当的值,这能帮助系统判断是否重置大小。系统自动尝试判断是否重置大小,但是这可能带来错误。 你也可以通过windowSoftInputMode属性对你的窗体设置最喜欢的soft input状态。
你可以通过InputMethodManager这个API来实现更精细的控制。
当你自己谢自己的文本编辑域的时候,你必须实现onCreateInputConnection(EditInfo)来返回一个InputConnection的实例,用来允许IME和你的文本编辑域来交互。
input methods: 一个IME实现为一个Service,典型的是继承InputMethodService。IME提供核心的InputMethod接口,尽管提供InputMethod通常是由InputMethodService来处理,而IME的实现只需要处理更高层的API。 更多信息参考InputMethodService
Security: 由于输入法必须有自由去完全掌控UI,和监听所有用户输入,所以这会导致很多安全问题。由于Android输入法框架允许任何第三方软件,所以注意限制IME的选中和交互。
以下是IMF背后的安全架构的关键点: 只允许系统通过BIND_INPUT_METHOD权限直接访问IME的InputMethod接口。通过绑定到要求这个权限的服务来强制实现这一点。所以系统可以保证没有不被信任的客户端在它的控制之外访问到当前的输入法。 IMF框架中有很多客户端进程,但仅有一个是活动的。不活动的客户端不能和IMF的键部分交互。这是通过下述机制实现的。 输入法的客户端只被授予访问输入法的InputMethodSession接口的权限。每一个客户端实现一个InputMethodSession接口的实例。当前IMF只处理和活动activity关联的那个InputMethodSession。普通IME(继承自InputMethodService)是通过AbstractInputMethodService强制实现的。但是自定义InputMethodSession实现的IME必须显示处理这一点。 只有活动的客户端的InputConnection可以采取操作。IMF判断每一个客户端是否活动,强制要求不活动的客户端调用InputConnection会被忽略。这确保了IME传递事件和文本输入到当前有焦点的UI。 屏幕关闭状态下IME永远不能和InputConnection交互。这一点通过使屏幕关闭状态下所有的客户端不活动来实现。这一点阻止了有问题的IME在用户无法看到它的行为情况下操作用户UI。 客户端应用程序可以请求选择一个新的IME,但是不能自己编程切换。这防止了恶意程序切换到自带的IME,当用户运行到另一个程序时,这个IME会保持运行。另一方面,IME程序可以编程实现切换到系统的另一个IME,这是因为IME本身已经拥有了用户输入的全部控制。 用户使用新的IME之前,必须显式地在设置里面允许一个新的IME。这就是对系统说,我(用户)已经知道了这个IME,可以用。出了问题用户负责怪不了系统。
调用下面代码:(第一次调用显示,再次调用则隐藏,如此反复),this指activity
[java:firstline[1]]&
单独显示隐藏软键盘:
<div class="tools" style="padding-top:3 padding-right:8 padding-left:10 font:normal normal normal 9px/normal Verdana,Geneva,Arial,Helvetica,sans- color: background-color:rgb(248,248,248); padding-bott还有很多小孩也没找到,你愿意帮助他们么?12:04 提问
anroid关于键盘监听问题
有两个问题。
1:怎么判断当时输入法切换的是英文或者手写或者汉字输入方式?
2:如图。怎么获取当前输入法上面的位置的文字(比如我现在输入的是jj,上面的文字是解决)
按时间排序
什么样的需求会让你监听键盘上的字呢,
其他相似问题> android中的EditText怎么屏蔽软键盘以及在屏蔽软键盘弹出其它对话框之类的控件的有关问题
android中的EditText怎么屏蔽软键盘以及在屏蔽软键盘弹出其它对话框之类的控件的有关问题
lulufanfan & &
发布时间: & &
浏览:121 & &
回复:0 & &
悬赏:0.0希赛币
android中的EditText如何屏蔽软键盘以及在屏蔽软键盘弹出其它对话框之类的控件的问题  1、在我们定义好EdiText件之后加上一句话来屏蔽软件盘
  editText.setInputType(InputType.TYPE_NULL);//此语句用来阻止掉输入法软键盘的弹出
  2、然后对该EditText控件进行点击监听
  edtText..setOnClickListener(new OnClickListener() {
&&&&&&&&&&&&&&&&&&&&&&&& public void onClick(View v) {
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&showDateDialog();
&&&&&&&&&&&&&&& });
  本例中是显示一个时间选择控件
  效果如图:
本问题标题:
本问题地址:
温馨提示:本问题已经关闭,不能解答。
暂无合适的专家
&&&&&&&&&&&&&&&
希赛网 版权所有 & &&

我要回帖

更多关于 搜狗输入法软键盘放大 的文章

 

随机推荐