Tech Sketch Bucket of Technical Chips by TIS Inc.

Google Glass開発第一歩~(2)音声入力とタッチジェスチャを使ったユーザインタフェース

Pocket

先日開催されたGoogle I/O 2014では、日本向けのExplorerプログラム開始のアナウンスはありませんでした。日本全域に散らばるガジェット愛好者が期待していたため残念ではありますが、気を取り直してglasswareの作り方を見ていくことにしましょう。今回からはエンタープライズシステムのフロントエンドとして利用可能ないくつかの機能をピックアップして実装方法を紹介していきます。

前回のブログ では、Google Mirror APIを使ってサーバからglassへの通知を実装しました。この方式のメリットは、glass側にapkをインストールする必要がないこと、シンプルではありますがglassに最適なフォーマットでテキストや画像を表示すること、などがあります。しかし、一方、glass側にapkをインストールしないということにより、複雑なユーザとのインタラクションは犠牲になります。具体的には、Google Mirror APIで利用できるインタラクションは、固定的なオプションメニューからの返信、削除、共有等のメニューを選択できるようにする程度のユーザインタフェースとなります。タップやスワイプなどのタッチジェスチャ入力に独自の振る舞いを定義することはできません。

さて、このブログでは、glass型端末がエンタープライズシステムのフロントエンドとして活用できる可能性を検証したいと考えています。上記のようなユーザインタフェースの制限を考えると、Google Mirror APIはあまり適切なフレームワークとはいえません。そこで、今後はglass型端末に特徴的なユーザインタフェースを検証してみます。まず今回は、google glassが現時点では他のglass型と一線を画していると思われる、音声入力タッチジェスチャによるユーザインタフェースを紹介します。

なお、本ブログの内容は、2014年6月10日に公開されたXE18.1および2014年6月末時点の Developerサイト に従って記載しています。Google glassのSDKは発展途上であり、アナウンスなく大きく変更されることがありますので、正式リリースまでは リリースノート などで常に最新の情報を確認しておく必要があります。

サンプルアプリケーションの仕様

今回作成したアプリケーションはglasscatという名前で githubに公開 しています。Glasscatは、ユーザインタフェース以外の実装を簡素化するために、 以前のブログ でも利用した、 The Cat API というサービスを利用します。このサービスは、RESTでリクエストを投げるたびに異なる猫の画像を返してくるサービスです。

Glasscatの主な仕様は以下の通りです。

  • アプリケーションを起動すると、定期的に猫の画像を更新する。
  • 更新頻度の変更、およびアプリケーションの終了はメニュー操作にて行う。
  • 更新頻度の変更は音声により数値(ミリ秒)を入力する。
  • アプリケーションの起動およびメニュー操作は音声入力とタッチジェスチャの双方にて可能とする。

Glasscatの画面遷移を図1に示します。音声入力とタッチジェスチャをともに実装する場合、このような単純なアプリケーションでもかなり複雑になります。なお、この遷移図では省略されていますが、実際にはスワイプダウン(上から下へのスワイプ)と呼ばれる、通常のandroid端末で「戻る」ボタンに相当する操作についても考慮する必要があります。

glasscat-summary.png

図1. Glasscatの画面遷移。

3つのUXパターンとimmersion

Glass Development Kit (GDK)を利用したアプリケーションでは、 (1) periodic notifications、(2) ongoing task、(3) immersionという、 3種類のUXパターンが推奨されています 。以前はstatic card、live card、immersionというように分類されていましたが、実際のアプリケーションはこれらを組み合わせて使うため、現在はより利用目的に適したデザインパターンで呼ばれるようになりました。それぞれの特徴を簡単に記します。

  1. Periodic notificationsパターン: Timelineにstatic cardを挿入するだけの簡単なアプリケーション。
  2. Ongoing taskパターン: Serviceとして継続的に実行し、timeline上のlive cardコンテンツ(remote view)を定期的に更新するアプリケーション。Cardをタップすることでmenu activityを呼び出してインタラクションを行うことができます。
  3. Immersionパターン: Immersionはserviceではなくactivityで実装します。Timeline上のcardではないため、タップやスワイプ時の処理も自由に記述できる、制約の少ないアプリケーションです。

さて、今回は音声入力とタッチジェスチャを使います。タップやスワイプといったタッチジェスチャは、immersionパターン以外ではmenu activityやtimeline操作に限定されており、オーバーライドすることができません。したがって、タッチジェスチャを使用する場合には必ずimmersionパターンでアプリケーションを作ることになります。

音声入力のパターン

GDKでは、以下の通り、 3種類の音声入力パターンが推奨されています

  1. Main voice commandsパターン: Home cardから"ok glass"の音声入力があったときにアプリケーションを呼び出すパターン。
  2. Contextual voice commandsパターン: アプリケーションのactivityで"ok glass"の入力があったときにコンテクストメニューを呼び出すパターン。
  3. Speech recognitionパターン: Google音声認識機能を利用するパターン。

以下、それぞれについて実装方法の概略を説明します。

①Main voice commandsパターン

Google glassにインストールされたアプリケーションは、Home card(時刻と"ok glass"が表示されているcard)から"ok glass"に続いて音声で起動することができます。通常のandroid端末ではランチャーと呼んでいるしくみで、voice triggerと呼ばれています。たとえば、glasscatでは、"ok glass"に続いて"show cats"と発声することでアプリケーションを呼び出します。このしくみを提供する機能がmain voice commandsです。
Google glassでは、タップによるアプリケーションの選択リストにも同じしくみが使われています。したがって、main voice commandsを実装していないアプリケーションは、ユーザが直接起動する手段をもっていない、ということになります。

認識させる文字列の定義

Main voice commandsで認識させる文字列はxmlリソースで定義します。具体的には、res/xml/<my_voice_trigger>.xmlというファイルに以下のように記述します。

この例では、直接文字列を書かず、res/values/strings.xmlを引用しています。これは普通のstringリソースです。

Voice triggerの設定

次に、このリソースをhome cardアプリケーション(いわゆるランチャー)に認識させる必要があります。具体的には、AndroidManifest.xmlの該当するactivityまたはserviceに対して、intent-filterおよびmeta-dataを記述します。Meta-dataのandroid:resourceには先ほど定義したxmlリソースのファイル名から拡張子を除いたものを指定します。

以上で、このアプリケーションのmain voice commandの設定は終了です。

Permissionの設定

Googleによると、main voice commandsはgoogleによって正式に採用されたコマンド文字列を使うべきであり、それ以外は、com.google.android.glass.permission.DEVELOPMENTというpermissionとともに使わなければならない、とのことです。"Show cats"は正式に採用された文字列ではありませんので、AndroidManifest.xmlにこの設定を行う必要があります。

なお、このpermissionを使用しているアプリケーションはPlayなどでの販売に支障があるかもしれません。この仕様が今度正式版のリリースまでにどのようになるか、開発者としては注視しておく必要があります。

②Contextual voice commandsパターン

次に、contextual voice commandsを使用します。Glasscatでは、「更新頻度の変更、およびアプリケーションの終了はメニュー操作にて行う」という部分です。
Contextual voice commandsについても、main voice commandsと同様、com.google.android.glass.permission.DEVELOPMENTというpermissionを設定しなければ任意の文字列を使うことはできません。

Menuリソースの準備

まず、menuリソースを準備します。ここで準備するmenuリソースは、通常androidで使うものとまったく同じです。階層化することもできます。
Glasscatでは、res/menu/main.xmlに定義されています。

フィーチャの設定

Contextual voice commandsは、対象となるactivityにcom.google.android.glass.view.WindowUtils.FEATURE_VOICE_COMMANDSというフィーチャを設定します。この設定を行うことにより、図2のように常時"ok glass"というメッセージが出て、ユーザからの音声入力を受け付けるようになります。

cat.png

図2. Contextual voice commandsを実装した画面。下方に"ok glass"の文字列が見える。

通常このフィーチャはActivity.onCreate()で設定します。また、この機能を利用するときには画面オフの機能を停止するためのフラグandroid.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ONも設定しておくほうがよいでしょう。

Menuの生成

次に、voice commandが呼び出された際に開くmenuを生成します。具体的には、Activity.onCreatePanelMenu()をオーバーライドして、先ほど準備したmenuリソースについて、MenuInflater().inflate()します。

Menu選択時の処理

最後に、Activity.onMenuItemSelected()をオーバーライドしてmenu選択時の処理を記述します。

③Speech recognitionパターン

3つの音声入力パターンの最後は、音声認識(speech recognition)です。音声認識を使うことで、ユーザが発生する任意の音声を文字列に変換することができます。
通常のandroid端末では独自の画面設計をすることもありますが、google glassでは、画面構成や操作方法の混乱を回避するため、標準で用意されているSpeechRecognizer Activityを利用するほうがよいでしょう。

Intent発行

Google glass標準のSpeechRecognizerを呼び出すには、android.speech.RecognizerIntent.ACTION_RECOGNIZE_SPEECHというintentを発行します。REQUEST_NUMBERは、Activity.onActivityResult()側で呼び出し元を一意に認識するためにアプリケーションが指定する独自コードです。

このintentが発行されると、図3のようにglass標準のactivityが後続の処理を行います。

speech-recognition.png

図3. Glass標準の音声入力activity。ここでは、プロンプトとして"Interval?\n(milliseconds)"を設定している。

Intentが返すデータの処理

Intentが音声認識を完了すると、Activity.onActivityResult()が呼び出されます。このとき、認識された文字列の候補がリストとして渡されますので、適宜選択して利用します。

Permissionの設定

音声認識を使用する際には、AndroidManifest.xmlで以下のpermissionを設定する必要があります。

音声入力の使い方

さて、google glassが提供している音声入力パターンの実装方法について説明してきました。ここでは、全般的な感想を記します。

  • 3つの音声入力パターンはそれぞれ使いみちが異なります。それぞれの特性を知って使い分けることが必要です。
  • 英語のみ対応している現状では日本語話者が広く汎用的に使うことはまだ難しいため、今後の日本語認識機能の提供が期待されます。
  • Glass型端末はタブレットやスマートフォンと比較して、マイクの距離が遠くなり、騒音の多い場所では認識精度が著しく低下する可能性があります。実際に、静かな喫茶店などでは非常に高い認識精度を示しますが、戸外では大きな声を出さなければ認識させることができません。
  • ここまで触れませんでしたが、3つの音声入力パターンはすべてgoogleの音声認識機能を活用しています。つまり、google側の音声認識サーバを利用しています。したがって、エンタープライズシステムとして利用するためには、外部サーバを利用することが機密情報の漏えいに該当しないかの確認が必要となります。実際には、業務によっては認められないケースも多いでしょう。

タッチジェスチャ入力

次に、音声入力とおなじくgoogle glassに特徴的なタッチジェスチャ入力について説明します。

タッチジェスチャ入力の実装

タッチジェスチャ入力を実装するには、検出したいタッチジェスチャをサポートするlistenerインタフェースを実装します。現在、listenerには以下のものがあり、それぞれ、com.google.android.glass.touchpad.GestureDetectorクラスに定義されています。

  • Baselistener: 基本的なタップやスワイプを検出する。
  • FingerListener: 指の本数の変化を検出する。
  • ScrollListener: 1本の指による横方向のスクロールを検出する。
  • TwoFingerScrollListener: 2本の指による横方向のスクロールを検出する。

Listenerの設定

まず、Activity.onCreate()にて、com.google.android.glass.touchpad.GestureDetectorを作成し、listenerを登録します。以下の例では、activity自体がlistenerインタフェースを実装しています。

onGenericMotionEvent()のオーバーライド

次に、Activity.onGenericMotionEvent()をオーバーライドして、作成したGestureDetectorMotionEventを渡します。

イベント処理の実装

最後に、listenerのonGesture()をオーバーライドし、具体的な処理を実装します。

タッチジェスチャの使い方

Immersionにおけるタッチジェスチャの機能は通常のandroid端末の操作とよく似ていますが、決定的な相違点があります。それは、glassではタッチのポイントを細かく設定できないことです。したがって、タッチジェスチャより細かい操作を行うためには、OpenCVなどを用いて手の動きなどを認識する、いわゆるジェスチャ認識を実装する必要があります。しかし、ジェスチャ認識を使っても、文章などの細かい入力を行うことはできません。エンタープライズシステムでglass型端末を活用するには、簡素な入力で十分となるような業務プロセスの工夫をしなければならないでしょう。

今後の連載について

次回は、QRコードを利用した簡単な在庫管理アプリケーションを作成する予定です。

エンジニア採用中!私たちと一緒に働いてみませんか?