LIFULL Creators Blog

LIFULL Creators Blogとは、株式会社LIFULLの社員が記事を共有するブログです。自分の役立つ経験や知識を広めることで世界をもっとFULLにしていきます。

ウェアラブルな世界

こんにちは。Android 衛藤です。

ネクストにはクリエイターの日というものがあり、通常業務から外れて新しい技術等に取り組む機会が与えられます。
非常に魅力的なこの制度、今回初参加させていただくことになりました。
デザイナー1名とエンジニア2名、計3人での取り組みとなります。

取り組む内容

Android Wearアプリの開発です。

新しい技術は早いうちに学びたい、と思っていたので
ちょうどよい機会になりそうです。

様々なメーカーからAndroid Wearが出てきていますが、
どんな使い方が本当に便利なのか?
まだ出てきたばかりなだけに、いろんな可能性を秘めているウェアラブルの世界。
今後どんな風に便利になっていくか楽しみです。

Android Wearアプリを開発するときの注意

本家のDocumentはしっかりと書かれていました。
https://developer.android.com/design/wear/index.html
こちらに、開発する際のアドバイスがたくさんあります。

また、スマホやタブレットとまったく違うため、デザインに関する注意もあります。

  • ユーザが操作する際に他の作業を止めるようなことをしない
    料理、食事、歩きながら、走りながら等、時計型デバイスは何かをしながら扱うのに最適なので、
    デバイス操作のたびに他の作業を止めてしまうのはナンセンス。 たとえば、メールが来てアーカイブする、スケジュールの通知が来てスケジューラにセットする、
    などの一連の操作は"5秒以内"に収める。

  • 大き目のジェスチャーに
    上記のとおり、何かをしながら操作することが多いウェアラブルデバイス。
    少しでも大き目のボタンやリストを作りましょう。

  • カードを表示する時を第一に考える
    ウェアラブルは「必要なときに、必要なコンテンツを」が大切。
    必要と思われるシチュエーションを整理し、どんなときに見せれば便利かを考えましょう。
    あまり必要じゃない時にコンテンツを出しすぎると、ユーザにミュートされてしまいます。

  • 一つの情報で、簡潔に
    できるだけ見せたい情報に絞っていきましょう。
    多いと感じたら、本当にすべての情報が必要か?または複数ページに分離してしまうことを検討しましょう。

  • 視覚的にデザインする
    どうすれば、ユーザがアプリから素早く情報を得て、作業にすぐに戻れるかを意識してデザインしましょう。
    バックグラウンドのイメージが、見せたいメッセージを後押ししているか、など。

  • 肩たたきしない
    ウェアラブルは常にユーザに触れています。 人と会話しているときに、いきなり後ろから肩を叩かれるとどう思いますか?
    デバイスのバイブレーションや音で同じようなことをしすぎないようにしましょう。

今回やること

機能は二つ、

  • 通知の連携
  • 道案内(Navigation)

二つだけなのですが、UI考えたり、実際のデバイスとの連携がどんな感じになるのか全くわからなかったため、 思い通りにいかないことが最初はほとんどでした。
何か情報がないか検索してもあまり記事が多くないため、試行錯誤しながらの開発・・・
たぶんAndroidが出たばかりの頃もこんな感じだったんでしょう。

特にUIに関してはどんな見せ方がよいのか、また実装として実現可能かの判断があまりつかず、 UIや画面遷移を考え直すこともしばしばありました。

Handheld(スマホ)とWearの連携

Handheldとペアリングさえしておけば、自動的にWearにも通知が出ます。
Wear側でボタンアクション等追加する場合は、基本的にはHandheld側でPendingIntentを発行します。
これまで通りPendingIntent.getActivity()で画面を開く、PendingIntent.getBroadcast()でBroadcastすることが可能です。

ただし、WearアプリのActivityを開く場合はWear側からstartActivityさせる必要があります。
この辺りを最初知らないと戸惑いますが、DataApiやMessageApiを使うことで実現が可能になります。

今回実現した内容は
1. PendingIntentを仕込んだNotificationを発行(Handheld)
2. Wear側でのActionを受け取ってWearableとコネクションを張る(Handheld)
3. コネクション確立後にMessageApiを使ってWearableに送信(Handheld)
4. Wear側でメッセージ受け取ったらstartActivity()させる(Wear)

少し面倒くさい方法ですが、これくらいしか方法はなさそうです。
以下、一応サンプルコードです。

Handheld側

Handheld側からWearへ任意のパスを指定してメッセージを送る

for (String node : nodes) {
    PendingResult<MessageApi.SendMessageResult> result
            = Wearable.MessageApi.sendMessage(mGoogleApiClient, node, "/start/SampleActivity", null);
    result.setResultCallback(new ResultCallback<MessageApi.SendMessageResult>() {
        @Override
        public void onResult(final MessageApi.SendMessageResult sendMessageResult) {
            if (!sendMessageResult.getStatus().isSuccess()) {
                Log.d(LOG_TAG, "send message failed");
            } else {
                Log.d(LOG_TAG, "send message success");
            }
        }
    });
}

いろんなサンプルだとsendMessage().await()してるのが多いですが、await使えないときはsetRersultCallbackで実装しているonResultで結果を受け取ります。

Wearable側

Wear側ではパスで判別して処理を行います。
サービスかリスナーで実装しますが、ここではWearableListenerServiceを継承したクラス内でメッセージを受け取ります。

@Override
public void onMessageReceived(final MessageEvent messageEvent) {
    Log.d(LOG_TAG, "onMessageReceived");
    if (messageEvent.getPath().equals("start/SampleActivity")) {
        Intent intent = new Intent(this, SampleActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);
    } else if (messageEvent.getPath().equals("start/OtherPath")) {
        // 他の処理
        // ここからWear自身にNotification発行したり
    }
}

ちなみに、Handheld側とWearable側で同じkeystoreで署名しないとメッセージが届かないようで、少しはまりました。
それぞれのbuild.gradleで同じkeystoreを指定してしまえばOKです。

signingConfigs {
    debug {
        storeFile fle('キーストアのパス')
    }
}

MessageApiではパスと一緒にbyte配列のデータを送信することができますが、
DataApiを使うとMapの形式で任意のデータの送信が可能です。

Wear側で出来ること

onMessageReceived()やonDataChanged()で受け取ったデータをWearのActivity側に通知する場合、 受け取ったServiceからBroadcastを投げることで実現しました。 ほかにも方法はありそうです。

今回はとある場所までの道案内をカードでWear側で見せる機能があるのですが、 Activty側ではFragmentGridPagerAdapterを使用して、道案内のカードを表示させています。

また、SensorManagerも今まで通り使えるのでコンパス作ったり、自由にViewをカスタマイズすることも可能です。
ただあまり複雑なことをWearでやりすぎると、シンプルさが失われたり電池の消費が激しくなったりと、 よろしくないことがたくさんあるので、出来るだけ複雑な処理はHandheld側で行わせるようにしています。

全体を振り返り

Android Wearで何ができるのかを模索しながら活動をしてきましたが、
なかなか良いものが出来上がりました。
やはり今までのAndroidとは使い勝手が違うため、 制約にはまったり、どういう見せ方がよいのか悩みどころがたくさんありましたが、 Android Wearがどんなものなのかがざっと理解できた気がします。

最初の方に書いた注意事項にもありますが、思ったより画面が小さいため見せたい情報を欲張りすぎると見づらくなるし、 複雑な操作をさせるとユーザは離れて行ってしまいます。
シンプル・簡単な操作でユーザの興味を引く、Android Wearを開発する上で一番重要になりそうだと感じました。

Android Wearはまだ新しい技術、これからどんな便利なアプリが出てくるのか楽しみです。
同時に、これからも便利なアプリをいち早く世の中に送り出していきたいと再認識させられた活動でした。