更改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 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的地方去返回相应的值,这样就改变了默认的键盘值

你可能感兴趣的:(技术总结)