fastapple's blog

時系列関係なく、情報を追記・分割・統合などします。ブログに記載の内容のうち、引用ではなく、私自身が記載している文章・コードなどについては、自由にご利用ください。

OK,Googleというのが面倒くさい問題を少し緩和する。(adbでOK,Google)


さて、ちょっと前にOK,Googleと発声するのが面倒くさい問題を書いたが、今回はちょっと視点が異なる。Androidだと画面オフになっている場合、画面をまずオンにしてから発声しなければいけない。ロックされている場合、設定によっては、音声で同時にロックを解除できる場合もあるが、自動解除には、自分の声であると認識される必要があったりする。(あくまでロックされた状態からの発生の場合のはなし)まあこの辺、Google HomeであればいつでもOK,Googleと発声すれば「ピロン」と応答してくれるんだから、商品として差別化できていると言えるかもしれない。※他にもGoogle Homeにしかないメリットとかあるのだろうけど、今持っていないので、よく知らない。

そこで、せっかくadbが使える環境が整ってきたので、powershellからokgoogleと打ち込むだけで、adbでつながっていれば、すぐに「ピロン」と反応し、聞き取り画面になるスクリプトを考えた。結論からいうと、以下のようになる。
okgoogle.ps1とでもして読み込めばいい。

#OK,GOOGLEと発話する代わりのことをするコマンド
#パターンロックは解除していない。
#対象は1台
function okgoogle
{
	adb shell am start -a android.intent.action.VOICE_COMMAND
	adb shell input keyevent 82
}

端末のロックは解除された状態にすること。SmartLockを駆使すれば、自宅では解除しておく。の、ようなことができる。パターンロックなどが解除されているなら、画面がオフのままになっていても、上記コマンドのみで大丈夫だ。

上記の意味について、書く。
Androidは、インテントと呼ばれるものを送り合うことで、要するにメッセージ指向型プログラミングをある意味実現している。こういった議論については、以下のURLが詳しく記載されているようなので、貼っておく。(今回の話から脱線しているので、読み飛ばしても問題ない。)

ubiteku.oinker.me

さて、adbでは、インテントをデバイスへ送りこむことができる。以下のURLには、インテントの一覧がある。参考にされたい。

d.hatena.ne.jp

上記から、音声認識を開始するには、ACTION_VOICE_COMMANDを使えばいいとわかる。
文字列の先頭のACTION_をはずしたものを、android.intent.action.の後に続ける。
つまり、ACTION_VOICE_COMMANDを利用する場合は、
android.intent.action.VOICE_COMMANDとなる。
adb shellに入って、これをam start の-aオプションに与える。これで、このインテントを実行せよということになる。
それでは、adb shell input keyevent 82は?input keyevent 82は、メニューキーをおす操作に相当する。実はAndroidは待受状態のまま音声認識を開始できるが、たとえば待受状態のまま「明日の天気は?」と聞いてもよいのだが、回答を得るには待受状態を解除しなければいけない。だから、まず音声認識をしたあとで、メニューキーを押すことで待受状態を解除している。ちなみに、いきなりkeyevent 82を送り込んで待受状態を解除しようとすると、失敗する場合がある。おそらくタイムラグ的な関係だろう。その点、Intentは時間がかかっても読み込んでくれるので、これを先にしてAndroidが十分起きている状態になってからキーイベントを送り込むのがベターだろう。

ここで一度Google Homeと比較して、利点と弱点を列記する。

GoogleHomeの利点
→いきなりOK,Googleといっても反応してくれる。
→その他もってないからわからんけどいろいろあるかもしれない。

Android端末上のGoogle Assistantの弱点
1.OK,Googleと言ってもスリープ状態のときに反応してくれない。
2.端末をロックしていると、ロックを解除しろとか言われる。

さて、Android端末上のGoogle Assistantの弱点として挙げた1,2は、ある程度緩和する方法がある。
1への対応…たとえば、adb shell input keyevent 82を30分間隔で送り込む。(画面のスリープの設定を30分にした上で)
2への対応…家でロックしないように、smart lockを活用する。

2はすぐにできそうだ。上記で記載したokgoogleコマンドを利用する前提にもなっているので、smart lockコマンドは活用したい。もっとも、ロックをどうしても解除しておきたくないということもあるだろうから。adbからロックの解除までできればいいのでそこは課題だ。(技術的にはできる)

1については、powershellでやりたい派からすると、powershellのジョブを登録して、30分おきにジョブ実行してやれば解決しそうだ。ただ、画面が暗くならないので、電池を食うというデメリットがあるが。