ひぃ

Androidのお話。


端末サイズによって同じアプリの同じ画面でも、IMEが出たりでなかったりすると障害が。

原因を調べると、以下のコードで処理がわかれていた。*1

/frameworks/base/services/java/com/android/server/InputMethodManagerService.java
    @Override
    public InputBindResult windowGainedFocus(IInputMethodClient client, IBinder windowToken,
          ・
        ・
        ・

                // Should we auto-show the IME even if the caller has not
                // specified what should be done with it?
                // We only do this automatically if the window can resize
                // to accommodate the IME (so what the user sees will give
                // them good context without input information being obscured
                // by the IME) or if running on a large screen where there
                // is more room for the target window + IME.
                final boolean doAutoShow =
                        (softInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST)
                                == WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE
☆                      || mRes.getConfiguration().isLayoutSizeAtLeast(
☆                              Configuration.SCREENLAYOUT_SIZE_LARGE);
                final boolean isTextEditor =
                        (controlFlags&InputMethodManager.CONTROL_WINDOW_IS_TEXT_EDITOR) != 0;

                // We want to start input before showing the IME, but after closing
                // it.  We want to do this after closing it to help the IME disappear
                // more quickly (not get stuck behind it initializing itself for the
                // new focused input, even if its window wants to hide the IME).
                boolean didStart = false;

                switch (softInputMode&WindowManager.LayoutParams.SOFT_INPUT_MASK_STATE) {
                    case WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED:
☆                      if (!isTextEditor || !doAutoShow) {
                            if (WindowManager.LayoutParams.mayUseInputMethod(windowFlags)) {
                                // There is no focus view, and this window will
                                // be behind any soft input window, so hide the
                                // soft input window if it is shown.
                                if (DEBUG) Slog.v(TAG, "Unspecified window will hide input");
                                hideCurrentInputLocked(InputMethodManager.HIDE_NOT_ALWAYS, null);
                            }
☆                      } else if (isTextEditor && doAutoShow && (softInputMode &
                                WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != 0) {
                            // There is a focus view, and we are navigating forward
                            // into the window, so show the input window for the user.
                            // We only do this automatically if the window can resize
                            // to accommodate the IME (so what the user sees will give
                            // them good context without input information being obscured
                            // by the IME) or if running on a large screen where there
                            // is more room for the target window + IME.
                            if (DEBUG) Slog.v(TAG, "Unspecified window will show input");
                            if (attribute != null) {
                                res = startInputUncheckedLocked(cs, inputContext, attribute,
                                        controlFlags);
                                didStart = true;
                            }
                            showCurrentInputLocked(InputMethodManager.SHOW_IMPLICIT, null);
                        }
                        break;
                    case WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED:
   
          ・
        ・
        ・


ふむふむ。
isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_LARGE)がtrueの時にIMEを表示するのか・・。*2
コメント部分を心もとない英語力で意訳すると

「画面おっきいんだぁ♪有効活用するためにIME出しちゃうね♪」

って感じです。たぶん。


ということで、画面サイズが画面サイズが480x640以上だとIMEが強制的に出るわけでした。*3

IME出したくないなら

getWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

ってやってねって言っといた。


※画面サイズはgetDefaultDisplayで取れる値かな。たぶん・・。*4

*1:ソースはJB(4.1.2)ベースだよん

*2:XLARGEな端末でもLARGE/NORMAL/SMALLのフラグがたってるのでこの条件に一致する。

*3:ICSからナビゲーションバーがオンスクリーンで表示される端末もあり、このナビゲーションが除外されたサイズでConfigurationのフラグが変化するみたいです。なので解像度が480x640以上なだけでなく、ナビゲーションバーの高さを覗いた時のサイズが480x640以上の場合に上記の条件に一致するみたい。

*4:http://d.hatena.ne.jp/tateisu/20111207/1323203657