更改Android 默認鍵盤映射值

更改Android InputManagerService默認鍵盤映射值

在通常情況下我們使用android手機或者平板連接外接鍵盤,默認的外接鍵盤映射值都是美式鍵盤,或者說是標準鍵盤,然而全世界並非只是用這一種鍵盤,在意大利,日本等國還擁有自己獨特的鍵盤,因此就需要設置他們自己的鍵盤映射值

frameworks/base/packages/InputDevices/res/raw/keyboard_layout_turkish.kcm

比方說在土耳其鍵盤下的 shift + 2 的值爲 /,我們假設需要將這個值 改爲 “

key 2 {
 label:                              '2'
 base:                               '2'
 shift:                              '"' //我們在這裏將默認值改爲"
 ralt:                               '\u00a3'
}

當然在這個目錄下對三十多個國家的特殊鍵盤映射都做了設置,但是主要國家都聚集在西方,比如日本等國也是特殊的鍵盤映射這裏就不包括

keyboard_layout_arabic.kcm
keyboard_layout_azerbaijani.kcm	
keyboard_layout_belgian.kcm	
keyboard_layout_brazilian.kcm	
keyboard_layout_bulgarian.kcm	
keyboard_layout_croatian_and_slovenian.kcm	
keyboard_layout_czech.kcm	
keyboard_layout_danish.kcm	
keyboard_layout_english_uk.kcm	
keyboard_layout_english_us.kcm	
keyboard_layout_english_us_colemak.kcm	
keyboard_layout_english_us_dvorak.kcm	
keyboard_layout_english_us_intl.kcm	
keyboard_layout_english_us_workman.kcm
keyboard_layout_estonian.kcm	
keyboard_layout_finnish.kcm	
keyboard_layout_french.kcm	
keyboard_layout_french_ca.kcm	
keyboard_layout_german.kcm	
keyboard_layout_greek.kcm	
keyboard_layout_hebrew.kcm	
keyboard_layout_hungarian.kcm	
keyboard_layout_icelandic.kcm	
keyboard_layout_italian.kcm	
keyboard_layout_latvian_qwerty.kcm	
keyboard_layout_lithuanian.kcm	
keyboard_layout_norwegian.kcm	
keyboard_layout_persian.kcm	
keyboard_layout_polish.kcm	
keyboard_layout_portuguese.kcm	
keyboard_layout_russian.kcm	
keyboard_layout_russian_mac.kcm	
keyboard_layout_slovak.kcm	
keyboard_layout_spanish.kcm	
keyboard_layout_spanish_latin.kcm	
keyboard_layout_swedish.kcm	
keyboard_layout_swiss_french.kcm	
keyboard_layout_swiss_german.kcm	
keyboard_layout_turkish.kcm	
keyboard_layout_ukrainian.kcm	

我們可以參考這個方法制作我們特殊的鍵盤映射值,android爲我們提供了一個類似overrlay的地方

frameworks/base/data/keyboards/Generic.kcm

在這個地方就可以改默認全語言的默認值

那如果我們要動態的去更換剛連接鍵盤的映射值,應該如何入手

需要在InputManagerService中監聽連接鍵盤後返回的默認值

frameworks/base /services/core/java/com/android/server/input/InputManagerService.java

 private String getDefaultKeyboardLayout(final InputDevice d) {
    final Locale systemLocale = mContext.getResources().getConfiguration().locale;
    // If our locale doesn't have a language for some reason, then we don't really have a
    // reasonable default.
    if (TextUtils.isEmpty(systemLocale.getLanguage())) {
        return null;
    }
    final List<KeyboardLayout> layouts = new ArrayList<>();
    visitAllKeyboardLayouts(new KeyboardLayoutVisitor() {
        @Override
        public void visitKeyboardLayout(Resources resources,
                int keyboardLayoutResId, KeyboardLayout layout) {
            // Only select a default when we know the layout is appropriate. For now, this
            // means its a custom layout for a specific keyboard.
            if (layout.getVendorId() != d.getVendorId()
                    || layout.getProductId() != d.getProductId()) {
                return;
            }
            final LocaleList locales = layout.getLocales();
            final int numLocales = locales.size();
            for (int localeIndex = 0; localeIndex < numLocales; ++localeIndex) {
                if (isCompatibleLocale(systemLocale, locales.get(localeIndex))) {
                    layouts.add(layout);
                    break;
                }
            }
        }
    });

    if (layouts.isEmpty()) {
    //在此方法中,如果用戶未設置默認鍵盤將返回null
        return null;
    }

    // First sort so that ones with higher priority are listed at the top
    Collections.sort(layouts);
    // Next we want to try to find an exact match of language, country and variant.
    final int N = layouts.size();
    for (int i = 0; i < N; i++) {
        KeyboardLayout layout = layouts.get(i);
        final LocaleList locales = layout.getLocales();
        final int numLocales = locales.size();
        for (int localeIndex = 0; localeIndex < numLocales; ++localeIndex) {
            final Locale locale = locales.get(localeIndex);
            if (locale.getCountry().equals(systemLocale.getCountry())
                    && locale.getVariant().equals(systemLocale.getVariant())) {
                return layout.getDescriptor();
            }
        }
    }
    // Then try an exact match of language and country
    for (int i = 0; i < N; i++) {
        KeyboardLayout layout = layouts.get(i);
        final LocaleList locales = layout.getLocales();
        final int numLocales = locales.size();
        for (int localeIndex = 0; localeIndex < numLocales; ++localeIndex) {
            final Locale locale = locales.get(localeIndex);
            if (locale.getCountry().equals(systemLocale.getCountry())) {
                return layout.getDescriptor();
            }
        }
    }

    // Give up and just use the highest priority layout with matching language
    return layouts.get(0).getDescriptor();
}

我們可以在幾個renturn的地方去加log,看看在設置對應國家時返回的getDescriptor()究竟是什麼,這樣我們就可以在renturn null的地方去返回相應的值,這樣就改變了默認的鍵盤值

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章