GDKで動的なGlasswareを作成する方法には、LiveCardを使用する方法とImmersionという方法が存在します。その二つの方法で同じアプリを作成してみたところ、処理の構築に大きな差異があることがわかりました。
その具体的な内容については本文から。
※今回の記事は昨日神戸大学の塚本教授が主催されているウェアラブルイベントに登壇した内容を再掲載しています。
ウェアラブルイベントについてはこちらへ。
Google Glassで動作するネイティブアプリを作成する方法にはGDKを利用しますが、GDKで動的コンテンツを作成する場合には下記の2種類の方法が存在します。
Immersion
timelineから外れ、単独で動的コンテンツの描写処理を行います。そのため、ユーザ入力のイベントはスワイプダウンを除き、全て取得できます。
スワイプダウンが取得できない理由は、Glass上Androidの戻るボタンのような処理が優先されるためです。
ImmersionはAndroidアプリを作成する方法とほぼ同様に作成することができます。
LiveCard
timeline上に存在し、動的コンテンツを描写します。そのため、ユーザー入力のイベントの取得には限りがあります。
例えば、スワイプ処理はtimeline上での処理が優先されるためLiveCardでは取得できません。
今回はこの2種類の方法でほぼ同様の動作を行うアプリを作成し、アプリ構築にどのような差異が現れるかをシーケンス図を用いて比較してみます。
まず、作成したアプリですが基本的な動きは下記の図のようになります。
今回はスロットゲームを作成してみました。
このアプリをImmersionで作成すると下記のシーケンス図になります。
Immersionの場合、メニューを表示させるActivity(※以降MenunActivity)を初期起動とします。
次に、表示されたメニューよりスタートメニューが選択させると、実際のスロット描写が行われるActivity(※以降SlotActivity)に画面遷移します。
今回はSlotActivityでスロットゲームの描写を全て行う為、タップジェスチャーもSlotActivityで取得します。
その方法が以下になります。
[SlotActivity.java]
//GestureDetector.BaseListenerインターフェイスを実装
public class SlotActivity extends Activity implements GestureDetector.BaseListener {
private GestureDetector mDetector;
mDetector = new GestureDetector(this).setBaseListener(this);
@Override
public boolean onGenericMotionEvent(MotionEvent event) {
return mDetector.onMotionEvent(event);
}
@Override
//onGestureをオーバーライドし、発生したジェスチャーを取得
public boolean onGesture(Gesture gesture) {
if (gesture == Gesture.TAP) {
return true;
//※タップされた際の処理を記述※
}
return false;
}
}
これはAndroidでもほぼ同様な仕組みになるかと思います。
スロットゲームを終了させるためには、スワイプダウンすることでMenunActivityに戻り、更にスワイプダウンすることでアプリが終了し、Timelineに戻ります。
では次にLiveCardで作成した場合です。
LiveCardをTimelineに表示させるためにはservice始動でアプリを呼び出し、seviceでLiveCardの生成を行います。
その方法が以下になります。
[SlotService.java]
private LiveCard mLiveCard;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (mLiveCard == null) {
mLiveCard = mTimelineManager.createLiveCard(LIVE_CARD_TAG);
mLiveCard.setDirectRenderingEnabled(true).getSurfaceHolder().addCallback(mSlotDrawer);
//LiveCardがタップされた際に立ち上がるActivityの設定
Intent menuIntent = new Intent(this, MenuActivity.class);
menuIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
mLiveCard.setAction(PendingIntent.getActivity(this, 0, menuIntent, 0));
//LiveCardをtimelineに表示
mLiveCard.publish(PublishMode.REVEAL);
} else {
// TODO(alainv): Jump to the LiveCard when API is available.
}
return START_STICKY;
}
更にLiveCardの描写を行うViewに独自Listenerを実装します。
LiveCardがタップされるとメニュー用Activity(※以降MenunActivity)に遷移し、メニューが表示されます。
Startメニューが選択されると、独自リスナーでStartメニューが実行されたことを取得し、LiveCardでスロットの描写処理が開始します。
スロットの描写が行われている最中にタップをした場合も、一旦MenuActivityでジェスチャーを取得し、独自リスナーにスロットを止める処理が実行されたことを渡し、Viewでそれに対応する描写処理が行われるという流れになります。
以下、独自リスナーの内容の一部になります。
public class Slot {
/**
* Interface to listen for changes on the {@link Slot}.
*/
public interface SlotListener {
/** Slot has started. */
public void onStart();
/** Slot has stoped. */
public void onStop();
}
private SlotListener mListener;
/**
* Starts the slot.
*/
public void start() {
//※途中省略※
if (mListener != null) {
mListener.onStart();
}
}
/**
* Stops the slot.
*/
public void stop(){
if (mListener != null){
mListener.onStop();
}
}
/**
* Sets a {@link SlotListener}.
*/
public void setListener(SlotListener listener) {
mListener = listener;
}
}
LiveCardではスロットを終了させるためには、メニューでゲーム終了を選択することにより、サービスがunBindされアプリが終了されます。
今回ImmersionとLiveCardの両者を作成し、処理の違いが明らかになったことで両者の特性がわかりました。
■Immersion■
Immersionで作成したアプリを起動した場合、アプリを終了させるまで他のtimeline上のカードの動作は一旦中断され、更新等が行われないため、そのアプリ単独で集中した動作が行える。
timelineから外れることにより、自由度の高い実装が行えるが、他のアプリとの並行動作は行えない。
■LiveCard■
timeline上に存在し、バックグラウンドで動作するため、他のtimeline上にあるカードの更新等も随時取得することが可能。
また、アプリを終了することなく、他のアプリを並行して動作させることが可能。
今回作成したスロットアプリは、単純にコーディングという部分ではimmersionの方が、ジェスチャーイベントも簡単に取得できて作りやすいと感じました。
しかし、スロットアプリを起動している最中にtimeline上のカードの更新等を一時的に止めてしまうことになるため、それに不都合が生じる場合は、LivaCardで作成を行わなければなりません。
どちらを選択するかによって、コーディングが大幅に変わってきますので、アプリの用途をしっかりと踏まえて開発方法を選択しましょう。
㈱ブリリアントサービス 大阪開発部 開発課 大田啓子




0 件のコメント:
コメントを投稿