みなさん Android TV はご存知でしょうか?これは Android を搭載したテレビや、TV に接続することができる Android 端末のことを指します。TV のリモコンを操作する感覚で、Android を操作することができるよう、UI が最適化されています。

有名なものだと Google が出している Nexus Player が挙げられます。こちらは日本でも発売されており、2月27日 に 12,800円 で発売されました。

本記事ではこの Android TV 向けアプリの作り方とさまざまな Tips について紹介したいと思います。

Android TV のアプリを作成するにあたって、手元に Nexus Player もしくは Android TV 搭載の TV があると良いでしょう。 無い場合でも、エミュレータが動くので問題なく開発を行うことができます。

まずは作ってみよう。

とにかく、こういった新しいものはまず触れてみるというのが一番いいと思いますので、まずはプロジェクトを作成し、動かしてみましょう。

前提条件

本記事は、Android Studio を使用した場合の作成方法を書いております。Eclipse ADT で実装を行うこともできると思いますが、あまりオススメは出来ません。

また、SDK tools は最新を使用し、Target SDK バージョンは 5.0 (API 21)以上 になるため先にインストールしておきましょう。

プロジェクトの作成

さて、前提条件で話したように今回は Android Studio を使用してアプリを作成するので、まずは Android Studio を立ち上げましょう。そして以下の画像にあるメニュー内の Start a new Android Studio project をクリックします。

studio top

すると、Project の名前を設定するところが出てくるので、適当に決めて先に進みます。

project name

次が重要な画面です。 ここで、使用する Target Device を Android TV に設定します。 こうすることで、Android TV 用のアプリを作成するために必要な設定がされたプロジェクトを作成することが出来ます。

select device

このあとは、Activity の形を選択する画面や、Activity name を決定する画面等が出てきますが、このへんも特にこだわりが無ければそのまま先に進みましょう。 以下の画像の Finish ボタンを押すことで、Android TV 用のプロジェクトが作成されます。

activity name

実はプロジェクトが作成された時点で、すでにある程度動くアプリが完成されています。 なのでまずはそのままビルドし、動きを見てみるといいと思います。

これで、Android TV 用のプロジェクトが作成することが出来ました。

Android TV 用アプリの構成  

基本構成は、普通のAndroid アプリと変わりません。 普通にアクティビティがあり、そこにビューが乗っている形になります。それではどこが違うのかというと、そのビューの置き方が違います。Android TV 用アプリのメインとなるビュー構成はカードビューです。

というのも、Android TV はあくまでもTVに乗るものであるため、画面の操作にはリモコンを使用します。 そのため、操作がしやすいようにカード状のビューを並べてそれを選択するような感じになっています。もちろん、これらのビューを 1 から作るのはとても大変なので、それを手助けしてくれるライブラリが用意されています。 それが、後述する LeanbackLibrary です。

もう一つ特殊なのが AndroidManifest ファイルへの記述です。 こちらもそれなりの作法があり、その通りに実装しないと動かないもしくは審査に落ちるといったことになってしまいます。

AndroidManifest

起動時のアクティビティ

Android Manifest の中で、一番違う部分としては一番最初に画面に出すmain の activity の intent-filter の中身になると思います。その実装が以下になります。

 <intent-filter>
     <action android:name="android.intent.action.MAIN" />

     <category android:name="android.intent.category.LEANBACK_LAUNCHER" />
 </intent-filter>

intent.action.MAIN はおなじみの書き方だと思いますが、カテゴリがちょっと違います。 android アプリでは、LAUNCHER をカテゴリに設定するのが普通かと思われますが、Android TV の場合は、LEANBACK_LAUNCHER 言うものを設定します。
こう書くことで、起動時のActivity を指定することが出来ます。

パーミッション

先の項で作成したプロジェクトの manifest ファイルを見に行くと、デフォルトで以下のパーミッションが付与されているのが分かると思います。

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />

<uses-feature
    android:name="android.hardware.touchscreen"
    android:required="false" />

<uses-feature
    android:name="android.software.leanback"
    android:required="true" />

feature で指定されているのが、leanback です。 これを指定しておく必要があります。

これに加えての設定を行う必要があります。

<uses-feature
    android:name="android.hardware.microphone"
    android:required="false" />

この設定を行わないと、アプリを申請する際に表示されるダウンロード可能端末一覧に Android TV の端末が表示されません。 また、後述する Android TV の項でも触れていますが、この設定を書かないとアプリの審査が通りません! これは結構はまる部分かと思いますので要注意です。

LeanbackLibrary

Leanback Library とは、Android のサポートライブラリ v17 にある機能で、Android TV の主要な画面要素を提供してくれるライブラリです。 Gradle でビルドする際には以下の実装を書く必要があります。

com.android.support:leanback-v17:21.0.0

実は、前項で作成したプロジェクトでは、デフォルトでこのライブラリを使用するよう設定がされています。

次に、この Leanback Library の主要なクラスについて紹介します。

BrowseFragment

このフラグメントは主にメインの画面などに使用するものです。
左側にナビゲーションドロワーのようなビューを持ち、そこにジャンルのようなヘッダを並べ、各グループへと遷移することが可能な画面です。

イメージが以下になります。イメージに使用したのは Android TV 版の google play のトップ画面です。

browseFragment の例

このフラグメントでは、タイトルの設定やドロワー部分の色の設定、左上に表示する検索ボタンの色などを設定することが出来ます。

以下に MainFragment でそれらを設定しているメソッドのコードから一部抜粋します。

    private void setupUIElements() {

        ...一部抜粋

        //タイトルに文字列を設定する
        setTitle("Android TV テスト");

        //ドロワーのデフォルト状態を設定
        setHeadersState(HEADERS_ENABLED);

        //ドロワー部分の背景色設定
        setBrandColor(Color.BLACK);

        //検索ボタンの色設定
        setSearchAffordanceColor(getResources().getColor(R.color.search_opaque));
    }

これらは、先ほど作成したプロジェクトで記述されていると思いますので、一度じっくりコードを眺めてみるとよいでしょう。 setHeadersState に設定できる値は以下の3つです。

名前 説明
HEADERS_ENABLED ヘッダーをデフォルトで表示する
HEADERS_HIDDEN ヘッダーはデフォルトで表示されていないが、表示自体は可能
HEADERS_DISABLED ヘッダーの表示自体が不可能

ここで言うヘッダーが左のドロワー部分を指しています。

BrowseFragment には setAdapter というメソッドがあり、そのメソッドにデータを管理するアダプターを設定することで、画面へデータの表示を行います。 その時に便利なのが、ArrayObjectAdapterというクラスです。
このクラスは、Presenter というクラスを継承したサブクラスもしくは、条件によって Presenter を使い分ける事のできる ClassPresenterSelector というものを使用してインスタンス化します。
これらは、まず Presenter にデータが渡された時にそれをビューとしてどのように表示するかということを書きます。 その後、ArrayObjectAdapter にデータを渡すとそれを Presenter に記述したとおりに表示してくれるというものです。

ちなみにこの ArrayObjectAdapter は Android TV アプリではどの画面でも使用するとても重要なクラスです。

詳しい使い方についてはプロジェクトを読み解いてもらうのが一番早いと思いますので、ここでは Presenter について少し触れる程度にしておきます。
以下コードの一部を抜粋したものです。

public class ContentItemPresenter extends Presenter {

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent) {

        //はじめに1度呼ばれるメソッド
        //この中でビューホルダーのインスタンスを作成しそれを返す

        mContext = parent.getContext();
        ImageCardView cardView = new ImageCardView(mContext);
        cardView.setFocusable(true);
        cardView.setFocusableInTouchMode(true);
        cardView.setBackgroundColor(mContext.getResources().getColor(R.color.white));
        return new ViewHolder(cardView);
    }

    @Override
    public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object item) {

        //ビューホルダーに値がバインドされるたびに呼ばれるメソッド

        if(item instanceof ContentItem){
            ContentItem content = (ContentItem)item;
            //ContentItem というアイテムが来た時の処理を記述。
        }
    }

    @Override
    public void onUnbindViewHolder(Presenter.ViewHolder viewHolder) {
        //ビューが非表示になる際に呼ばれるメソッド。
    }

    static class ViewHolder extends Presenter.ViewHolder {

        private ImageCardView mCardView;

        public ViewHolder(View view) {
            super(view);
            mCardView = (ImageCardView) view;
        }

        //割愛...
    }
}

このプレゼンターをアダプターに設定しておくことで、アダプター内のデータに変更があった場合、onBindViewHolder 内に記述した通りに、 ビューを変更することが出来ます。 ちなみにこの ContentItemPresenter は独自に実装したものですので、先ほどのプロジェクトには存在していませんが、中身は初期プロジェクトのサブクラス化してあるプレゼンターとさほど変わりません。

DetailsFragment

このフラグメントは名前の通り詳細画面等に使用するフラグメントになります。
詳細画面に必要な画面構成要素をラップしていて、画面中央に大きなカードビュー、その下に関連項目等を並べる。 といった使用方法が一般的です。

画面中央に設置する大きなカードビューも、左にサムネイル、右に詳細情報といった使い方をすることが出来るとても便利な画面構成要素になります。

DetailsFragment の例

この画面には左部ドロワーはなく、中央に目立つようにビューを配置することが可能になっています。

先ほどの BrowseFragment と同様に setAdapter にアダプタを設定するわけですが、この中央に表示するビューを表現するには普通の Presenter ではなく、 それようにカスタマイズされた Presenter を使用する必要が有ります。

それが RowPresenter です。更には、それを継承し Detail 画面になるように調整した DetailsOverviewRowPresenter というプレゼンターというものも有ります。 よほどカスタマイズして使用しない場合にはこの DetailsOverviewRowPresenter を使用したほうがいいでしょう。 カスタマイズして使用する場合には RowPresenter を継承したサブクラスを作成することになりますが、こちらを作成するのは結構手間がかかります。

なのでできるだけ、DetailsOverviewRowPresenter を使用することが出来る設計を行うと良いかと思います。 今回はこの DetailsOverviewRowPresenter を使用しているコードを一部抜粋したいと思います。

//ところどころ省略

DetailsOverviewRowPresenter mDorPresenter = new DetailsOverviewRowPresenter(new DetailsDescriptionPresenter());
mDorPresenter.setBackgroundColor(getResources().getColor(R.color.detail_background));
mDorPresenter.setStyleLarge(true);
mDorPresenter.setOnActionClickedListener(new OnActionClickedListener() {

    //ディテールビューの中にあるアクションが選択された時の処理を記述する。
    @Override
    public void onActionClicked(Action action) {}
});

//データが入力された時に、その型に合わせて使用するプレゼンターを変更する設定
ClassPresenterSelector ps = new ClassPresenterSelector();
ps.addClassPresenter(DetailsOverviewRow.class, mDorPresenter);

//アダプタに値を追加。
ArrayObjectAdapter adapter = new ArrayObjectAdapter(ps);
adapter.add(detailRow);

setAdapter(adapter);

ここで使用している derailRow というデータは、Row というクラスを継承して作成された model クラスです。

tips

審査

Android TV 用のアプリもまた、Google による審査を受ける必要があります。

審査内容は、

  • Android TV 用のガイドラインに沿った UI になっているのか。
  • Android TV で使用できないパーミッションが付与されていないか。
  • Android TV に載ることがないハードウェアの許可が外れているのか。
  • きちんとアプリとして動くものになっているのか。

などなど TV 用アプリとして必須の事柄を見るようです。

apk インストール方法

作成した Android TV 用のアプリを TV に転送する方法としては、実機とPCを直接つなぎ adb コマンドで転送するか、USBメモリに apk を入れそれを TV に接続するという 2 つの方法があります。

しかし、この 2 つ以外の方法を取らなくてはいけないこともあるかもしれません。そんな時に出来る方法をここでまとめておきたいと思います。

参考にしたサイト

ES File Explorer を Android TV にインストールする

 まずは、Android TV に apk ファイルをインストールするために必要な、ES File Explorer をインストールする必要が有ります。
 ちなみに、google play store (以下 store )に存在する、Android TV には対応していないアプリをインストールする際は、これと同様の方法で行うことが出来ます。

 はじめに、PC 版の store にアクセスし、Android TV の初期起動時に使用した google アカウントと同じものでログインします。
 store で「ES ファイルエクスプローラー」のページを開き、そのページ内のインストール、もしくはインストール済み と書かれたボタンをクリックします。すると以下のような画像が表示されます。

ES ファイルエクスプローラーインストール

 端末をお選びくださいと書かれている部分で、「No carrier Asus Nexus Player」 と書かれたもの(Nexus Player ではない場合は適宜読み替えてください)を選択し、インストールボタンをクリックすると、Android TV 側へアプリがインストールされます。 

 Android TV の方で、[Settings] > [Apps] に行くと ES File Explorer がインストールされていることを確認することが出来ます。  確認後、一度 ES ファイルエクスプローラーを開きます。そして、初回起動画面が終わったあとの画面を開いたままにしておいてください。  

Android 端末で apk を送信する

 ここからは一度 Android TV から離れ、スマートフォンもしくはタブレット(以下 Android 端末)での操作になります。
 まず、Android 端末を Android TV と同じ wifi につなぎます。
 Android TV に送信したい apk を、スマートフォン内に取り込みます。これで準備は完了です。

 Android 端末で ES ファイルエクスプローラーを開き(無い場合はインストールをお願いします)、取り込んだ apk を探します。
 見つけたら apk ファイルをロングタップすると、以下のメニューが表示されます。

ロングタップ

 画面右下の「他」を選択し、表示されるその他メニューの中から「送る」を選択します。  送るを選択すると、同じ wifi 内にある端末をスキャンする画面になります。成功すると以下の様な画像が表示されます。

ターゲット一覧

 一覧から Android TV にあたる端末を選択し、右下の送るボタンをタップします。タップすると、転送中画面になりますので、そのままにしてください。  ここで、Android TV 側に戻ります。転送画面が表示されていますので、リモコンを操作し OK ボタンを押します。保存場所を聞かれますので、任意の場所に保存してください。  これで転送完了です。  

インストール

 転送が成功すると、Success 画面が表示されます。 その画面内の Open を選択すると、Apk を開くことが出来ますので、そのまま Install ボタンを押してください。

 初回は、インストール時に、提供元不明アプリの許可を有効にする必要が有ります。 [Settings] > [Security & Restrictions] > [Unknown sources] を ON にしてください。

 インストールが完了したら、[Settings] > [Apps] 内にあるのでそこから立ち上げることが出来ます。

おまけ

 apkインストール方法の途中でおや?と思った方もいるかと思いますが、実は Android TV では特に調整していない普通の Android アプリも、物によっては動いてしまいます。 ただし、UI がスマートフォンもしくはタブレット用になっているので、リモコンでは操作できない部分もあると思いますが、端末によっては Bluetooth のマウスがつながったりもします。 それだけで、大体のアプリはそのまま動いてしまいます。 色々と試してみると面白いかもしれません。

おわりに

Android TV はまだ出たばかりで注目度もそこまで大きくないと思いますが、今のうちに知っておくことで後々ブームになった時に大きな武器になると思われます。 Android TV 用のアプリを作成しようと思っている方々の手助けになれたなら幸いです。