今天來了一個(gè)問題:軟鍵盤無法彈出。分析后是因?yàn)橄到y(tǒng)判斷當(dāng)前有外接硬鍵盤,就會(huì)隱藏軟鍵盤。但實(shí)際情況并不是這么簡單,該問題只有在特定條件下偶現(xiàn),具體分析過程就不說了,就是軟硬鍵盤支持上的邏輯問題。借著這個(gè)機(jī)會(huì)整理一下鍵盤檢測的過程。
Configuration
Android系統(tǒng)中通過讀取Configuration中keyboard的值來判斷是否存在外接鍵盤。Configuration中關(guān)于鍵盤類型的定義如下,
public static final int KEYBOARD_UNDEFINED = 0; // 未定義的鍵盤 public static final int KEYBOARD_NOKEYS = 1; // 無鍵鍵盤,沒有外接鍵盤時(shí)為該類型 public static final int KEYBOARD_QWERTY = 2; // 標(biāo)準(zhǔn)外接鍵盤 public static final int KEYBOARD_12KEY = 3; // 12鍵小鍵盤
在最常見的情況下,外接鍵盤未連接時(shí)keyboard的值為KEYBOARD_NOKEYS,當(dāng)檢測到鍵盤連接后會(huì)將keyboard的值更新為KEYBOARD_QWERTY 。應(yīng)用就可以根據(jù)keyboard的值來判斷是否存在外接鍵盤,InputMethodService.java中有類似的判斷代碼。
// 軟件盤是否可以顯示 public boolean onEvaluateInputViewShown() { Configuration config = getResources().getConfiguration(); return config.keyboard == Configuration.KEYBOARD_NOKEYS || config.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_YES; } 現(xiàn)在的問題就轉(zhuǎn)向Configuration的keyboard是如何更新的。在WindowManagerService.java中,應(yīng)用啟動(dòng)時(shí)會(huì)更新Configuration,相關(guān)代碼如下。
boolean computeScreenConfigurationLocked(Configuration config) { ...... if (config != null) { // Update the configuration based on available input devices, lid switch, // and platform configuration. config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH; // 默認(rèn)值為KEYBOARD_NOKEYS 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; // 遍歷輸入設(shè)備 for (int i = 0; i < len; i++) { InputDevice device = devices[i]; // 如果不是虛擬輸入設(shè)備,會(huì)根據(jù)輸入設(shè)備的flags來更新Configuration if (!device.isVirtual()) { ...... // 如果輸入設(shè)備的鍵盤類型為KEYBOARD_TYPE_ALPHABETIC,則將keyboard設(shè)置為KEYBOARD_QWERTY if (device.getKeyboardType() == InputDevice.KEYBOARD_TYPE_ALPHABETIC) { config.keyboard = Configuration.KEYBOARD_QWERTY; keyboardPresence |= presenceFlag; } } } ...... // Determine whether a hard keyboard is available and enabled. boolean hardKeyboardAvailable = config.keyboard != Configuration.KEYBOARD_NOKEYS; // 更新硬件鍵盤狀態(tài) if (hardKeyboardAvailable != mHardKeyboardAvailable) { mHardKeyboardAvailable = hardKeyboardAvailable; mH.removeMessages(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE); mH.sendEmptyMessage(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE); } // 如果Setting中SHOW_IME_WITH_HARD_KEYBOARD被設(shè)置,將keyboard設(shè)置為KEYBOARD_NOKEYS,讓軟件盤可以顯示 if (mShowImeWithHardKeyboard) { config.keyboard = Configuration.KEYBOARD_NOKEYS; } ...... }
新聞熱點(diǎn)
疑難解答
圖片精選