参考地址:http://blog.csdn.net/wq892373445/article/details/51767022

http://blog.csdn.net/qq_32034593/article/details/53065542

http://blog.csdn.net/DrakeBlue/article/details/39049495

第一种:(第二种方法中也提及了这个类的这个方法,但是修改的参数是mHardKeyboardEnabled,最后不推荐修改这个参数,不知道怎么情况。)

VR项目中,通过无线鼠标连接蓝牙来控制VR,但是蓝牙连接上后点击搜索框时无法弹出输入法键盘,这是有物理键盘造成的, 需屏蔽物理键盘来解决这个问题, 实现如下:
frameworks/base/services/Java/com/Android/server/wm/WindowManagerService.java 中的 computeScreenConfigurationLocked 方法 将hardKeyboardAvailable = false。

  // Determine whether a hard keyboard is available and enabled.boolean hardKeyboardAvailable =false;//config.keyboard != Configuration.KEYBOARD_NOKEYS;if (hardKeyboardAvailable != mHardKeyboardAvailable) {mHardKeyboardAvailable = hardKeyboardAvailable;mHardKeyboardEnabled = hardKeyboardAvailable;mH.removeMessages(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE);mH.sendEmptyMessage(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE);}if (!mHardKeyboardEnabled) {config.keyboard = Configuration.KEYBOARD_NOKEYS;}

第二种:

第一次写,写的不好请见谅

参考:
http://blog.csdn.net/DrakeBlue/article/details/39049495
http://blog.csdn.NET/hclydao/article/details/44240799
http://blog.csdn.Net/jdsjlzx/article/details/39495319

物理键盘映射过程:

手机/system/usr/keylayout/*.kl :内核将keyCode映射成有含义的字符串
KeycodeLabels.h : framework 将字符串映射成keyEvent的keyCode
frameworks/…/res/values/attrs.xml

- 主要部分:android.jar



一、问题描述:
当平板连接上蓝牙扫描枪(外接物理键盘)时候,不能弹出软键盘输入,需要打开系统的输入法选择界面关闭硬件物理键盘后才能调用弹出系统软键盘;

理想效果:
在平板连接上蓝牙扫描枪后仍可以调用系统软键盘输入,将系统的物理键盘默认设置为关闭状态,或不需要开启关闭物理键盘,

二、思路

1.首先:你要知道AndroidManifest.xml文件。这里这里有的信息对于理解程序又很大的意义。
2.学会使用grep命令。修改系统的源代码时候这个很重要,
3.当想修改一个程序时,先找到这个程序的位置,大部分只要修改framework 和package 两个文件夹下的内容
4.关键字,例如要修改statuBars。先使用hierarchyviewer查看statuBar属于那个部分。
5.根据图标,使用grep在framework中查找对应的位置。
6.然后就是修改程序了。

三、部分代码

Android版本源码

frameworks/base/services/Java/com/android/server/wm/WindowManagerService.java
关键代码:行6618 computeScreenConfigurationLocked()方法中
[java] view plaincopy在CODE上查看代码片派生到我的代码片

boolean hardKeyboardAvailable = config.keyboard != Configuration.KEYBOARD_NOKEYS;  if (hardKeyboardAvailable != mHardKeyboardAvailable) {  mHardKeyboardAvailable = hardKeyboardAvailable;  mHardKeyboardEnabled = !hardKeyboardAvailable;  mH.removeMessages(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE);  mH.sendEmptyMessage(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE);  }  if (!mHardKeyboardEnabled) {  config.keyboard = Configuration.KEYBOARD_NOKEYS;  }  

将mHardKeyboardEnabled直接改成false
这样改软键盘是能用但是物理键盘是用不了的

最后研究代码frameworks\base\services\core\java\com\android\server\wm\WindowManagerService.java
如果把updateShowImeWithHardKeyboard方法中的showImeWithHardKeyboard变量直接置为true,则可以实现软键盘与物理键盘的同时使用,
但此举修改影响范围很大,不推荐。

 public void updateShowImeWithHardKeyboard() {//modified by Janning for enble the HardKeyboard startfinal boolean showImeWithHardKeyboard = Settings.Secure.getIntForUser(mContext.getContentResolver(), Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD, 0,mCurrentUserId) == 1;//final boolean showImeWithHardKeyboard = true;//modified by Janning for enble the HardKeyboard endsynchronized (mWindowMap) {if (mShowImeWithHardKeyboard != showImeWithHardKeyboard) {mShowImeWithHardKeyboard = showImeWithHardKeyboard;mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);}}}
  • 10

后续继续研究代码发现在WindowManagerService.java的computeScreenConfigurationLocked方法中有通过判断当前物理键盘类型来控制是否同时启用软件盘的处理逻辑:

boolean computeScreenConfigurationLocked(Configuration config) {if (!mDisplayReady) {return false;}// TODO(multidisplay): For now, apply Configuration to main screen only.final DisplayContent displayContent = getDefaultDisplayContentLocked();// Use the effective "visual" dimensions based on current rotationfinal boolean rotated = (mRotation == Surface.ROTATION_90|| mRotation == Surface.ROTATION_270);final int realdw = rotated ?displayContent.mBaseDisplayHeight : displayContent.mBaseDisplayWidth;final int realdh = rotated ?displayContent.mBaseDisplayWidth : displayContent.mBaseDisplayHeight;int dw = realdw;int dh = realdh;if (mAltOrientation) {if (realdw > realdh) {// Turn landscape into portrait.int maxw = (int)(realdh/1.3f);if (maxw < realdw) {dw = maxw;}} else {// Turn portrait into landscape.int maxh = (int)(realdw/1.3f);if (maxh < realdh) {dh = maxh;}}}if (config != null) {config.orientation = (dw <= dh) ? Configuration.ORIENTATION_PORTRAIT :Configuration.ORIENTATION_LANDSCAPE;}// Update application display metrics.final int appWidth = mPolicy.getNonDecorDisplayWidth(dw, dh, mRotation);final int appHeight = mPolicy.getNonDecorDisplayHeight(dw, dh, mRotation);final DisplayInfo displayInfo = displayContent.getDisplayInfo();synchronized(displayContent.mDisplaySizeLock) {displayInfo.rotation = mRotation;displayInfo.logicalWidth = dw;displayInfo.logicalHeight = dh;displayInfo.logicalDensityDpi = displayContent.mBaseDisplayDensity;displayInfo.appWidth = appWidth;displayInfo.appHeight = appHeight;displayInfo.getLogicalMetrics(mRealDisplayMetrics,CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);displayInfo.getAppMetrics(mDisplayMetrics);mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager(displayContent.getDisplayId(), displayInfo);}if (false) {Slog.i(TAG, "Set app display size: " + appWidth + " x " + appHeight);}final DisplayMetrics dm = mDisplayMetrics;mCompatibleScreenScale = CompatibilityInfo.computeCompatibleScaling(dm,mCompatDisplayMetrics);if (config != null) {config.screenWidthDp = (int)(mPolicy.getConfigDisplayWidth(dw, dh, mRotation)/ dm.density);config.screenHeightDp = (int)(mPolicy.getConfigDisplayHeight(dw, dh, mRotation)/ dm.density);computeSizeRangesAndScreenLayout(displayInfo, rotated, dw, dh, dm.density, config);config.compatScreenWidthDp = (int)(config.screenWidthDp / mCompatibleScreenScale);config.compatScreenHeightDp = (int)(config.screenHeightDp / mCompatibleScreenScale);config.compatSmallestScreenWidthDp = computeCompatSmallestWidth(rotated, dm, dw, dh);config.densityDpi = displayContent.mBaseDisplayDensity;// Update the configuration based on available input devices, lid switch,// and platform configuration.config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;config.keyboard = Configuration.KEYBOARD_NOKEYS;config.navigation = Configuration.NAVIGATION_NONAV;int keyboardPresence = 0;int navigationPresence = 0;final InputDevice[] devices = mInputManager.getInputDevices();final int len = devices.length;for (int i = 0; i < len; i++) {InputDevice device = devices[i];if (!device.isVirtual()) {final int sources = device.getSources();final int presenceFlag = device.isExternal() ?WindowManagerPolicy.PRESENCE_EXTERNAL :WindowManagerPolicy.PRESENCE_INTERNAL;if (mIsTouchDevice) {if ((sources & InputDevice.SOURCE_TOUCHSCREEN) ==InputDevice.SOURCE_TOUCHSCREEN) {config.touchscreen = Configuration.TOUCHSCREEN_FINGER;}} else {config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;}if ((sources & InputDevice.SOURCE_TRACKBALL) == InputDevice.SOURCE_TRACKBALL) {config.navigation = Configuration.NAVIGATION_TRACKBALL;navigationPresence |= presenceFlag;} else if ((sources & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD&& config.navigation == Configuration.NAVIGATION_NONAV) {config.navigation = Configuration.NAVIGATION_DPAD;navigationPresence |= presenceFlag;}// 判断该物理设备的类型, InputDevice.KEYBOARD_TYPE_ALPHABETIC 是表示物理键盘设备if (device.getKeyboardType() == InputDevice.KEYBOARD_TYPE_ALPHABETIC) {config.keyboard = Configuration.KEYBOARD_QWERTY;keyboardPresence |= presenceFlag;}// 获取物理设备名称,判断是否是指定的名称,如果是则把 config.keyboard// 的属性置为 Configuration.KEYBOARD_NOKEYS ,如此则可以同时兼容软键盘// 物理键盘与软键盘可以同时启用// Add by Janning start// for show IME with HardKeyboardif (device.getName().equals("XXX-vinput-keypad")) {Slog.w("SLCODE", "the hard device name is: " + device.getName());config.keyboard = Configuration.KEYBOARD_NOKEYS;}// Add by Janning end}}if (config.navigation == Configuration.NAVIGATION_NONAV && mHasPermanentDpad) {config.navigation = Configuration.NAVIGATION_DPAD;navigationPresence |= WindowManagerPolicy.PRESENCE_INTERNAL;}// Determine whether a hard keyboard is available and enabled.boolean hardKeyboardAvailable = config.keyboard != Configuration.KEYBOARD_NOKEYS;if (hardKeyboardAvailable != mHardKeyboardAvailable) {mHardKeyboardAvailable = hardKeyboardAvailable;mH.removeMessages(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE);mH.sendEmptyMessage(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE);}if (mShowImeWithHardKeyboard) {config.keyboard = Configuration.KEYBOARD_NOKEYS;}// Let the policy update hidden states.config.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO;config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO;config.navigationHidden = Configuration.NAVIGATIONHIDDEN_NO;mPolicy.adjustConfigurationLw(config, keyboardPresence, navigationPresence);}return true;}public boolean isHardKeyboardAvailable() {synchronized (mWindowMap) {return mHardKeyboardAvailable;}}public void updateShowImeWithHardKeyboard() {// 此处修改也可以实现物理键盘与软键盘的同时启用,即把showImeWithHardKeyboard 直接置为 true,// 但此方法影响太大,不推荐该方案,建议根据设备名称判断 修改config.keyboard 属性值(代码见上文)//changed by Janning start//modified by Janning for enble the HardKeyboard startfinal boolean showImeWithHardKeyboard = Settings.Secure.getIntForUser(mContext.getContentResolver(), Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD, 0,mCurrentUserId) == 1;//final boolean showImeWithHardKeyboard = true;//modified by Janning for enble the HardKeyboard end//changed by Janning endsynchronized (mWindowMap) {if (mShowImeWithHardKeyboard != showImeWithHardKeyboard) {mShowImeWithHardKeyboard = showImeWithHardKeyboard;mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);}}}
  • 1

当插入物理键盘后通知栏会弹出相应的选择键盘布局通知,对于该通知可以选择隐藏:
根据字符串查找到是在 frameworks\base\services\core\java\com\android\server\input\InputManagerService.java 中调用显示该通知的,
进一步分析代码发现是在 deliverInputDevicesChanged 方法中控制通知的显示。

InputManagerService.java

private void deliverInputDevicesChanged(InputDevice[] oldInputDevices) {。。。。。。。。。。。。。。。。if (missingLayoutForExternalKeyboard) {if (missingLayoutForExternalKeyboardAdded) {if (multipleMissingLayoutsForExternalKeyboardsAdded) {// We have more than one keyboard missing a layout, so drop the// user at the generic input methods page so they can pick which// one to set.showMissingKeyboardLayoutNotification(null);} else {// 如果只插入了一个物理键盘则判断该物理键盘的名称是否是指定的,如果是则不让其显示键盘布局的通知// Modify by Janning beginif (keyboardMissingLayout != null&& !keyboardMissingLayout.getName().equals("XXXX-vinput-keypad")) {showMissingKeyboardLayoutNotification(keyboardMissingLayout);}// Modify by Janning end}}} else if (mKeyboardLayoutNotificationShown) {hideMissingKeyboardLayoutNotification();}}mTempFullKeyboards.clear();}
  • 1

注意 注意 注意,重要的说三遍;

假如以上你都修改了,以为这样都OK了,那你就OUT了

看看下面的你或许根本不知道,慢慢研究吧!骚年

四、以下操作全在ubuntu系统下完成

可以参考:http://blog.csdn.net/y150481863/article/details/8023422
操作步骤(不具体说明):
1.下载好ubuntu系统之后。
2.在找到sdk位置(就是你的SDK 找到你用的那个系统,在到ubuntu修改)。
………………………..(做起来不是这么简单)
3.再用ub系统上生成.jar,再放在SDK里面

第三种:

Android系统在外接物理键盘的时候,可以在Settings的Language&Input设置中,将默认的输入设置设为软键盘还是物理键盘。

Android系统在检测到有外接USB键盘的时候,默认是启用物理键盘,而软键盘将会隐藏。如果需要启用软键盘,需要将物理键盘OFF掉。

现在,我们修改源代码,将这个物理键盘默认改为OFF。

通过Settings的代码,我们找到该Dialog是通过IIputMethodManager.aidl的showInputMethodPickerFromClient()方法通知另外的地方弹出的对话。

而showInputMethodPickerFromClient()方法的实现是在frameworks/base/services/Java/com/android/server/InputMethodManagerService.java中。

1795行,方法//

@Override
    public void showInputMethodPickerFromClient(IInputMethodClient client) {
        synchronized (mMethodMap) {
            if (mCurClient == null || client == null
                    || mCurClient.client.asBinder() != client.asBinder()) {
                Slog.w(TAG, "Ignoring showInputMethodPickerFromClient of uid "
                        + Binder.getCallingUid() + ": " + client);
            }

// Always call subtype picker, because subtype picker is a superset of input method
            // picker.
            mHandler.sendEmptyMessage(MSG_SHOW_IM_SUBTYPE_PICKER);
        }
    }

该Handler的处理在2050行;

@Override
    public boolean handleMessage(Message msg) {
        HandlerCaller.SomeArgs args;
        switch (msg.what) {
            case MSG_SHOW_IM_PICKER:
                showInputMethodMenu();
                return true;

case MSG_SHOW_IM_SUBTYPE_PICKER:
                showInputMethodSubtypeMenu();
                return true;
            ......

......

继续跟踪showInputMethodSubtypeMenu()方法; 2317行

private void showInputMethodSubtypeMenu() {
        showInputMethodMenuInternal(true);
    }

最后找到关键方法showInputMethodMenuInternal(); 2344行;

这个方法主要是获取系统输入法,然后进行弹框显示。而我们的物理键盘默认设置看在下面代码片段中。

final Switch hardKeySwitch =  ((Switch)mSwitchingDialogTitleView.findViewById(
                    com.android.internal.R.id.hard_keyboard_switch));
            Log.d(TAG, "input isEnabled: " + mWindowManagerService.isHardKeyboardEnabled());     
            hardKeySwitch.setChecked(mWindowManagerService.isHardKeyboardEnabled());

hardKeySwitch.setOnCheckedChangeListener(
                    new OnCheckedChangeListener() {
                        @Override
                        public void onCheckedChanged(
                                CompoundButton buttonView, boolean isChecked) {
                            mWindowManagerService.setHardKeyboardEnabled(isChecked);
                        }
                    });

我们看到该Switch的Checked设置是在调用的WindowManagerService的一个boolean值的get方法。接着往里走

/frameworks/base/services/java/com/android/server/wm/WindowManagerService.java

关键代码:行6618 computeScreenConfigurationLocked()方法中

boolean hardKeyboardAvailable = config.keyboard != Configuration.KEYBOARD_NOKEYS;
            if (hardKeyboardAvailable != mHardKeyboardAvailable) {
                mHardKeyboardAvailable = hardKeyboardAvailable;
                mHardKeyboardEnabled = !hardKeyboardAvailable;
                mH.removeMessages(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE);
                mH.sendEmptyMessage(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE);
            }
            if (!mHardKeyboardEnabled) {
                config.keyboard = Configuration.KEYBOARD_NOKEYS;
            }

这里将会读取物理键盘是否可用,如果可用将会赋值给mHardKeyboardEnabled为true,然后hardKeySwitch set的值将会是这个可用的true,

我这里将hardKeyboardAvailable取反赋给mHardKeyboardEnabled。

Android 如何在插入外接物理键盘时还能显示软键盘相关推荐

  1. Android --- 进入页面时,不弹出软键盘。当 EditText 被点击时不弹出软键盘,而是调用其他选择器,比如时间选择器等

    功能需求: 1.进入页面时,不弹出软键盘 2.当 EditText 被点击时不弹出软键盘,而是调用其他选择器,比如时间选择器等 搜索百度测试: 1.百度上说用 editText.setInputTyp ...

  2. android点击隐藏控件,Android编程实现点击EditText之外的控件隐藏软键盘功能

    本文实例讲述了Android编程实现点击EditText之外的控件隐藏软键盘功能.分享给大家供大家参考,具体如下: 工具类 ... public static void hideKeyboard(Co ...

  3. android 获取键盘回车键事件,设置软键盘回车键显示内容,点击空白处隐藏软键盘

    首先设置EditText的回车属性 drawable文件 @drawable/editcolor <?xml version="1.0" encoding="utf ...

  4. android点击软键盘外面的区域关闭软键盘解决办法

    很多时候在一个页面有多个输入框或者输入框加选择框的时候,我们需要根据用户的点击去关闭软键盘. 在Activity中加入以下代码即可 /**重写dispatchTouchEvent* 点击软键盘外面的区 ...

  5. 安卓之软键盘监听与切换软键盘状态和重新获取EditText焦点

    最近在工作中的时候遇到了关于使用ScrollView作为外层点击内部EditText弹出软键盘滑动页面的问题,百度了好久各种教程,但是对于我的页面来说没有一个有用的,自己花了1天时间终于搞定了,今天在 ...

  6. [iOS] UITextField隐藏软键盘心得(隐藏自身软键盘、点击Return自动转到下个文本框、轻触背景隐藏软键盘)...

    作者:zyl910 关于隐藏软键盘,网上的办法良莠不齐,大多是通过实现UITextFieldDelegate来隐藏软键盘,该方法代码较多,且在文本框很多的时不好处理.我经过搜索与摸索,找到了最佳的处理 ...

  7. 计算机软键盘怎么打开,如何打开软键盘,详细教您电脑怎么打开软键盘

    软键盘有什么好处?在网上付款或者要打开一些机密的文件需要输入密码,这时候软键盘就可以派上用场了,这也是为了防止木马记录键盘输入的密码.那么该怎么去打开软键盘呢?下面,小编就来跟大家介绍电脑打开软键盘的 ...

  8. Android中的EditText默认时不弹出软键盘的方法

    在做项目过程中 , 父 Activity 中 用 ViewPager 中 的子 ActivityEditText默认弹出软键盘.这是想屏蔽 软键盘 应该从父 Activity 中处理.处理子 Acti ...

  9. Android 类似淘宝 电商 搜索功能,监听软键盘搜索事件,延迟自动搜索,以及时间排序的搜索历史记录的实现

    最近跳槽去新公司,接受的第一个任务是在 一个电商模块的搜索功能以及搜索历史记录的实现. 需求和淘宝等电商的功能大体差不多,最上面一个搜索框,下面显示搜索历史记录.在EditText里输入要搜索的关键字 ...

最新文章

  1. 强化学习:如何处理大规模离散动作空间
  2. linux 32库路径,linux – 共享库如何在64位/ 32位混合系统中工作?
  3. 读《JavaScript dom编程艺术(第2版)》笔记 1-2
  4. 编译原理习题(含答案)——4-7语法分析——MOOC哈尔滨工业大学陈鄞配套_学习通_慕课堂
  5. 点击按钮,图片和按钮的文字发生改变
  6. junit单元测试断言_简而言之,JUnit:单元测试断言
  7. 经典问题之「分支预测」
  8. c语言定义数组a10 指定各元素,C语言填空题.doc
  9. 配置数据库连接池的时候。
  10. java实现PNG图片任意角度旋转
  11. IEBrowser IE升级工具 下载
  12. 互联网日报 | 贾跃亭宣布破产重组完成;小米发布首款OLED电视;湖南迎来首家本土航空公司...
  13. 计算机用户删除了怎么恢复出厂设置,四种电脑快速恢复出厂设置方法
  14. 下载微信账单用于分析
  15. 2019年的最新的最全的ava常见的面试题
  16. Matlab中测程序运行时间
  17. rpy角与旋转矩阵之间的转换(附完整代码)
  18. python分析股票MACD指标
  19. 计算机网络第一章1-28答案,北邮计算机网络 第一章 课后题答案
  20. 202112-1序列查询

热门文章

  1. 最全大数据技术知识体系
  2. Go语言---动态查询数据库
  3. myelicpes2019初次使用设置_实况足球2019(PES2019)全图文攻略官方操作指南
  4. 大数据开发技术与实践期末复习(HITWH)
  5. SpringBoot 系列教程(八十五):Spring Boot使用MD5加盐验签Api接口之前后端分离架构设计
  6. 开发网校系统要准备什么
  7. C++牛顿迭代法求根,用递归方法实现分析及代码
  8. Linux OpenCV + zBar 实现二维码识别
  9. 百度新闻搜索参数精解
  10. css球形颜色选择器,在CSS选择器中使用color颜色样式CSS代码