First write, write Bad please forgive me
Physical keyboard mapping process:
Mobile/SYSTEM/USR/KEYLAYOUT/*.KL: The kernel maps keycode to a meaningful string
Keycodelabels.h:framework map strings to KeyEvent KeyCode
Frameworks/.../res/values/attrs.xml
-
main parts: Android.jar
First, the problem description:
When the tablet connection on the Bluetooth scanner (external physical keyboard), you can not eject the soft keyboard input, you need to open the system Input method selection interface to turn off the hardware physical keyboard to call the system soft keyboard eject;
Ideal effect:
The system soft keyboard input can still be called after the Bluetooth scanner on the tablet connection, the physical keyboard of the system is set to off by default, or the physical keyboard is not turned off.
Second, the idea
1. First: You need to know the Androidmanifest.xml file. The information here is of great significance for understanding the program.
2. Learn to use the grep command. This is important when modifying the system's source code.
3. When you want to modify a program, first find the location of the program, most just modify the framework and package two folder content
4. Keywords, for example, to modify Statubars. First use Hierarchyviewer to see Statubar belongs to that section.
5. Based on the icon, use grep to find the corresponding position in the framework.
6. Then the program is modified.
Third, part of the code
Android version Source
Frameworks/base/services/java/com/android/server/wm/windowmanagerservice.java
Key code: Line 6618 computescreenconfigurationlocked () method
[Java] View plaincopy on code to see a snippet derived from my Code slice
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; }
change the mhardkeyboardenabled directly to false
so the soft keyboard can be used but the physical keyboard is not available
Last research code frameworks\base\services\core\java\com\android\server\wm\ Windowmanagerservice.java
If the Showimewithhardkeyboard variable in the Updateshowimewithhardkeyboard method is directly set to True, You can implement a soft keyboard with a physical keyboard,
but the scope of this modification is very large, not recommended.
public void Updateshowimewithhardkeyboard () {//modified by janning for enble the Hardkeyboard Start Final 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 synchronized (mwindowmap) {if (Mshowimewithhardkeyboard! = Showimewi Thhardkeyboard) {mshowimewithhardkeyboard = Showimewithhardkeyboard; Mh.sendemptymessage (H.SEND_NEW_CONFIGURATION) ; } } }
Follow-up study code discovery in the Windowmanagerservice.java computescreenconfigurationlocked method has the process logic to control whether the software disk is enabled at the same time by judging the current physical keyboard type:
Boolean computescreenconfigurationlocked (Configuration config) {if (!mdisplayready) {return false;} TODO (Multidisplay): For now, apply the Configuration to main screens only. Final Displaycontent displaycontent = getdefaultdisplaycontentlocked (); Use the effective "visual" dimensions based on rotation final 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 = Configurati Mnl Navigation_nonav) {config.navigation = Configuration.navigation_dpad; navigationpresence |= PresenceFlag;}//Judge the physicalThe type of device, inputdevice.keyboard_type_alphabetic, is the physical keyboard device if (device.getkeyboardtype () = = Inputdevice.keyboard_type_ alphabetic) {Config.keyboard = Configuration.keyboard_qwerty; keyboardpresence |= Presenceflag;}//Get Physical device name, Determines whether the specified name, if it is the Config.keyboard//property is set to Configuration.keyboard_nokeys, so you can simultaneously compatible with the soft keyboard//physical keyboard and soft keyboard can be enabled//Add by janning Start//For show IMEs with Hardkeyboard if (Device.getname (). Equals ("Xxx-vinput-keypad")) {SLOG.W ("Slcode", "the Hard de Vice name is: "+ device.getname ()); Config.keyboard = Configuration.keyboard_nokeys; }//Add by janning end} if (config.navigation = = Configuration.navigation_nonav && mhaspermanentdpad) {confi G.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 () {///modify This can also enable the physical keyboard and the soft keyboard while enabling, that is, the Showimewithhardkeyboard directly to true,// However, this method has too much impact and is not recommended, it is recommended to modify the Config.keyboard attribute value according to the device name (code see above)//changed by janning start//modified by janning for enble the Har Dkeyboard Start Final 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 end synchronized (mwindowmap) {if (mshowimewith Hardkeyboard! = Showimewithhardkeyboard) {mshowimewithhardkeyboard = Showimewithhardkeyboard; MH.sendEmptyMessage (H. Send_new_configuration); } } }
When you insert a physical keyboard, the notification bar pops up with the appropriate selection of keyboard layout notifications, which you can choose to hide:
Based on the string found to be called in Frameworks\base\services\core\java\com\android\server\input\inputmanagerservice.java to display the notification,
Further analysis of code discovery is to control the display of notifications in the Deliverinputdeviceschanged method.
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 {//If only one physical keyboard is inserted, determine if the name of the physical keyboard is specified, and if so, do not let it display a notification of the keyboard layout//Modify by janning begin if (keyboardmissinglayout! = null &A mp;&!keyboardmissinglayout.getname (). Equals ("Xxxx-vinput-keypad")) {showmissingkeyboardlayoutnotification ( Keyboardmissinglayout); }//Modify by janning End}}} else if (Mkeyboardlayoutnotificationshown) {hidemissingkeyboardlayoutnotification ()}} Mtempfullkeyboards.clear (); }
Pay attention to note that it is important to say three times; you have modified the above, you think this is OK, then you are out.
System Soft Keyboard >android How to force the system soft keyboard to be called when external physical keyboard?