算譜王におれはなる!!!!

偏りはあると思うけど情報技術全般についてマイペースに書くよ。

夢と魔法の待ち時間をAndroidWear対応した!

夢と魔法の待ち時間というAndroidアプリを趣味で開発しています。このアプリをAndroidWearに対応させました!Google Playよりダウンロードできます。

通知

Android電話やタブレットに届いた通知は、自動で接続しているAndroidWear端末(例えば時計)にも通知されます。Android4.1で追加されたBigTextStyleとかInboxStyleを適用した通知はWearでいい感じに表示されます。さらにWear用のAPIが追加されたので、これを使ってみました。

NotificationCompat.WearableExtenderインスタンスを作って、それをNotificationCompat.Builder#extendに渡すだけで通知にWear固有の設定ができるようになります。今回のリリースでは通知の背景画像の設定と、ページの追加をしています。

だいたいこんなコードを書きました。

private NotificationCompat.WearableExtender wearableExtender(
        final List<Attraction> attractions,
        final Bitmap attractionImage) {
    return new NotificationCompat.WearableExtender()
            // 背景画像の設定
            .setBackground(attractionImage)

            // ページの追加 (各アトラクション)
            .addPages(Lists.transform(attractions,
                new Function<Attraction, Notification>() {
                    @Override
                    public Notification apply(final Attraction attraction) {

                        // 1つのNotificationが1つのページに対応する
                        return new NotificationCompat.Builder(context)
                                .setContentTitle(attraction.getName())
                                .setContentText(attraction.getWaitTime() + "分待ち")
                                .build();
                    }
                }));
}

f:id:ngsw_taro:20140706111112p:plainf:id:ngsw_taro:20140706111119p:plain

Wearアプリ

Wear側にインストールするアプリにも対応しています。Wear側でアトラクションの待ち時間一覧を表示できて便利です。

電話(or タブレット)とWear間のデータ送受信

アトラクション情報(JSON)を電話側でダウンロードして、Attractionクラスのオブジェクトにデシリアライズしています。それをbyte配列にシリアライズしてWearに送信。Wearはbyte配列を受信し、Attractionオブジェクトにデシリアライズする、こんな感じになってます。

メッセージの送信には、Wearable.MessageApi#sendMessageを使用します。その引数の1つとして「パス」を指定する必要があります。このパスにより受信側でどんなメッセージが送られて来たか識別できるわけです。例えば"/land/attractions"とか"/sea/attractions"みたいな風に指定します。

Wear側での受信には、今回はMessageApi.MessageListenerをアクティビティで実装してメッセージをリスンする形にしました。実装すべきメソッドシグネチャpublic void onMessageReceived(MessageEvent)で、このMessageEventでメッセージのパスや内容(byte配列)が取れます。

@Override
public void onMessageReceived(final MessageEvent messageEvent) {
    final String path = messageEvent.getPath();
    final byte[] data = messageEvent.getData();

こういう感じでパスとメッセージ内容を取れて

final Optional<List<Attraction>> attractions = ByteUtils.deserialize(data);

シリアライズする*1

Wear用ビュー

Wear用のビューもいくつか用意されています。とりあえず今回は待ち時間情報をリスト表示したかったのでWearableListViewを使ってみました。使い方は普通のListViewとほとんど同じだと思います。setAdapterでアダプタを渡す必要がありますが、WearableListView用のWearableListView.Adapterを使います。このAdapterはいわゆるViewHolderを管理してくれるみたいなのですごく使いやすいです。

f:id:ngsw_taro:20140706112640p:plainf:id:ngsw_taro:20140706112652p:plain

apk配布

Wearアプリは電話(or タブレット)アプリにバンドルして配布するらしいです。電話にアプリをインストールするとシステムが自動でWear側にアプリをインストールしてくれます。Wearにアプリがインストールされていれば「Start ランドの待ち時間」、「Start シーの待ち時間」みたいにしゃべるとアプリが起動し、待ち時間一覧が表示されます。ぜひ夢と魔法の待ち時間を使ってパークを楽しんでください!!

f:id:ngsw_taro:20140706112631p:plain

届いた! (7/7追記)

届いたので早速使ってみた!いい感じ!これがあれば快適に遊べるはずです。

f:id:ngsw_taro:20140707223424j:plain

*1:ByteUtils#deserializeは自分で実装したやつ