はじめに
htmlを表示するAndroidアプリを扱っていて、
タブレットの再起動直後タップして他画面へ遷移、という動作を行おうとしたところ、
遷移が行われず、2回目のタップで遷移が行われた、ということがあったので、原因を調査しました。
試行錯誤の様子をネチネチ綴ります。
最初はアプリ上のブラウザにフォーカスがないからかと思った
単純に、初期表示のonLoad時に$(window).focus
すればいいんじゃない?
と思ってhtml側でを修正してみましたが、
tomcat再起動してタブレットを再起動した1回目はなぜか初回のタップで画面遷移ができるのに、
次再起動したらもう初回のタップで画面遷移ができないという...
ブラウザにフォーカスを当ててもだめ...
ということは画面に表示された部品にフォーカスが当たってたらいいとか?
動的にアプリ側からフォーカスを置くjavascriptを呼んでみる
androidアプリでhtml上にフォーカスを置くの、どうしたらいいんだろうと検索しまくると、
ここが似たようなことをやっているので参考にしてみました。
特に入力項目がない画面なので、暫定的にテキストボックスを置いて、
Text 1<input type='text' id='text1'/>
ここと同じようにjavascriptから下記を呼びます。
document.getElementById("text1").focus();
すると、Androidのキーボードが表示されてしまいますが、
ブラウザ上にフォーカスが乗って、初回のタップで画面遷移ができたではありませんか。
やったね!解決!
とはならなかった。だって、キーボードも表示されたくないし、テキストボックスもいらないから。
でも、これでブラウザにフォーカスが乗ってないから説が裏付けられそうです。
では、htmlに何かの部品を見えないように置いておいて、
その部品にフォーカスを置く感じにすれば、初回のタップで画面遷移ができるようになって解決でしょうか。
まずキーボードを出さないようにできないかな?
まずはキーボードを出さないようにするにはどうしたらいいか調べてみました。
readonlyを設定すればキーボードが出ないようです。
よし、これでいってみましょう。
Text 1<input type='text' id='text1' readonly='readonly'/>
?
あれ?フォーカスは乗っているのに、初回のタップで画面遷移ができません。
そもそもinputタグはhiddenにするとフォーカス置けない
キーボードを出さないようにしたら初回のタッチイベントが取得できない時点でもうこの案はダメなのですが、
諦め悪く調べていたら、inputタグは見えないようにhiddenにするとフォーカスが置けないということがわかりました。
最初からタッチイベントがちゃんと動いているか調べていればよかったのに
初心に帰ってタッチイベントが呼ばれたらログが出るようにしてみました。
やってみると1回目のタッチイベント、呼ばれていませんでした。
2回目のタッチイベントからは呼ばれますけど。
ということは、動的にフォーカス置く処理を呼ぼうが、初期処理で呼ぼうがぜんぜん関係ない話なのね。。。
原因はAndroidアプリ側にある
1回目だけタッチイベントが呼ばれないとかある?と思って検索を続けると、
Androidでタッチイベントが取得できないだと!という記事にたどり着きました。
同じ悩みを持った人がいる!
記事を読み進めると、解決策のエントリも発見!
これによると、ナビゲーションバーを隠す処理を入れたことによる影響のよう。
ナビゲーションバーは通常下記のように隠します。
View view = window.getDecorView();
view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN | c);
記事の説明によると、
この命令は、あくまで、ナビゲーションバーを“隠す”ものなのだ。
で、隠れた状態で、タッチすると、ナビゲーションバーが表示される。
このナビゲーションバーの表示に、1タッチ取られているから、初回のタッチは検出できず、ナビゲーションバーは一度表示されると、二度と隠れないので、そのままアプリのActivityにタッチイベントが通知される、という動作のようだ。
ということらしい。
今扱っているアプリは設定から常時ナビゲーションバーを非表示にしており、
加えて上記の処理を適用しているので、おそらくナビゲーションバーは不可視なだけで
実際は動いているのかもしれません。理屈はよくわからないが。
記事に従ってナビゲーションバーを隠す処理を下記のように変更したら
無事初回からタッチイベントが取得できました!やったー!
View view = window.getDecorView();
view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE | c);
ラターシュさんありがとう
こんなニッチな情報を残していてくれた方がいて、本当にありがたい。
なんならアマギフ送りたい。
参考サイト
Android WebView - Setting HTML Field focus using Javascript
Androidでタッチイベントが取得できないだと!
Androidでタッチイベントが取得できないだと!/ 解決編