TV ハードウェアに対応する

テレビのハードウェアは、他の Android デバイスとは大きく異なります。テレビにはタッチスクリーン、カメラ、GPS 受信機など、他の Android デバイスでよく使われるハードウェア機能がありません。また、テレビはセカンダリ ハードウェア デバイスに完全に依存しています: ユーザーがテレビアプリを操作するには、リモコンまたはゲームパッドを使用する必要があります。(入力方法の種類については、テレビ コントローラの管理をご覧ください)。

テレビアプリをビルドする際は、ハードウェア上の制限や テレビ向けハードウェアの操作要件を慎重に考慮する必要があります。アプリがテレビで実行されているかどうかを確認し、サポートされていない ハードウェア機能を処理します。

テレビデバイスをチェックする

テレビデバイスとその他のデバイスの両方で動作するアプリを作成している場合、アプリを実行するデバイスの種類をチェックし、アプリの動作を調整する必要があります。たとえば、Intent で起動するアプリの場合、テレビ向けアクティビティを起動するか、スマートフォン向けアクティビティを起動するかを判断するために、アプリ側でデバイスのプロパティをチェックする必要があります。

テレビデバイスでアプリが正常に動作するかどうかを判断するには、PackageManager.hasSystemFeature()メソッドを使用して そのデバイスがアプリのテレビモードで正常に動作するかどうかをチェックすることをおすすめします。次のサンプルコードは、 テレビデバイスでアプリが正常に動作するかどうかをチェックする方法を示しています。

Kotlin

const val TAG = "DeviceTypeRuntimeCheck"

val isTelevision = packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK)
if (isTelevision) {
    Log.d(TAG, "Running on a TV Device")
} else {
    Log.d(TAG, "Running on a non-TV Device")
}

Java

public static final String TAG = "DeviceTypeRuntimeCheck";

boolean isTelevision = getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK);
if (isTelevision) {
    Log.d(TAG, "Running on a TV Device");
} else {
    Log.d(TAG, "Running on a non-TV Device");
}

サポートされていないハードウェア機能を処理する

アプリのデザインと機能によっては、特定の ハードウェア機能を利用できないという事態を回避できる場合があります。ここでは、通常テレビで使用できないハードウェア機能やその検出方法と、代替機能について説明します。

サポートされていないテレビ ハードウェア機能

テレビの用途は他のデバイスと異なるので、他の Android デバイスで提供されることの多いハードウェア機能が ありません。このため、テレビデバイス向け Android システムでは 次の機能をサポートしていません。

ハードウェア Android の機能記述子
タッチスクリーン android.hardware.touchscreen
タッチスクリーン エミュレータ android.hardware.faketouch
電話 android.hardware.telephony
カメラ android.hardware.camera
近距離無線通信(NFC) android.hardware.nfc
GPS android.hardware.location.gps
マイク android.hardware.microphone
センサー android.hardware.sensor
縦向きの画面 android.hardware.screen.portrait

注: 一部のテレビ コントローラにはマイクがありますが、ここで説明するマイクのハードウェア機能と同じものではありません。コントローラのマイクは完全に サポートされます。

機能、サブ機能とその記述子の全一覧については、 機能リファレンスをご覧ください。

テレビのハードウェア要件を宣言する

Android アプリでは、機能を提供しないデバイスにインストールされないように、アプリ マニフェストでハードウェア機能の要件を宣言できます。テレビ向けに既存の アプリを拡張している場合は、テレビデバイスへのインストールを阻害する可能性のあるハードウェア要件 を宣言しているかどうかについて、アプリのマニフェストを詳細に見直す必要があります。

テレビで使用できないハードウェア機能(タッチスクリーンやカメラなど)をアプリで使用しているものの、テレビではその機能がなくても構わない場合は、アプリのマニフェストを編集して それが不要な機能であることを示します。次のマニフェストのコード スニペット では、テレビデバイスで使用できないハードウェア機能を不要と宣言する方法を示しています。これらの機能は、テレビ以外のデバイスでは使用できます。

<uses-feature android:name="android.hardware.touchscreen"
        android:required="false"/>
<uses-feature android:name="android.hardware.faketouch"
        android:required="false"/>
<uses-feature android:name="android.hardware.telephony"
        android:required="false"/>
<uses-feature android:name="android.hardware.camera"
        android:required="false"/>
<uses-feature android:name="android.hardware.nfc"
        android:required="false"/>
<uses-feature android:name="android.hardware.location.gps"
        android:required="false"/>
<uses-feature android:name="android.hardware.microphone"
        android:required="false"/>
<uses-feature android:name="android.hardware.sensor"
        android:required="false"/>
<!-- Some TV devices have an ethernet connection only -->
<uses-feature android:name="android.hardware.wifi"
        android:required="false"/>

注: 機能リファレンスで説明されているように、一部の機能には android.hardware.camera.frontのようなサブ機能があります。アプリで使用されるサブ機能も required="false" としてマークしてください。

テレビアプリのビルドを開始するで説明したように、テレビデバイス向けのすべてのアプリで、タッチ スクリーン機能が不要であることを宣言する必要があります。アプリでテレビデバイスでサポートされていない機能を 1 つ以上使用している場合は、マニフェストで該当する機能の android:required 属性の設定を false に変更します。

注: この値を true に設定してハードウェア機能が必要であることを宣言すると、アプリはテレビデバイスにインストールされず、Android TV のホーム画面ランチャーにも表示されません。

ハードウェア機能を暗示するパーミッションに注意する

uses-permission のマニフェストにおける宣言には、ハードウェア機能を暗示するものがあります。つまり、アプリ マニフェストでリクエストするパーミッションによっては、アプリがテレビ デバイスにインストールされず、使用できないことがあります。よくリクエストされる次のパーミッションでは、暗黙的なハードウェア機能の要件が作成されます。

権限 暗黙的なハードウェア機能
RECORD_AUDIO android.hardware.microphone
CAMERA android.hardware.camera
android.hardware.camera.autofocus
ACCESS_COARSE_LOCATION

android.hardware.location

android.hardware.location.network(対象 API レベル 20 以前のみ)

ACCESS_FINE_LOCATION

android.hardware.location

android.hardware.location.gps(対象 API レベル 20 以前 のみ)

ACCESS_WIFI_STATE
CHANGE_WIFI_STATE

android.hardware.wifi

一部のテレビデバイスはイーサネット接続のみです。

暗黙的なハードウェア機能要件のパーミッション リクエストの一覧については、 uses-feature ガイドを参照してください。アプリが上記の機能のいずれかをリクエストする場合は、 uses-feature 宣言をマニフェストに含めて、不要であることを示します。android:required="false"

注: アプリのターゲットが Android 5.0(API レベル 21)以降で、ACCESS_COARSE_LOCATION または ACCESS_FINE_LOCATION パーミッションが使用されている場合は、テレビデバイスにネットワーク カードまたは GPS 受信機がなくてもそのテレビデバイスにアプリをインストールできます。

アプリのハードウェア機能をオプションにする場合は、実行時にこれらの機能が利用できるかをチェックしてからアプリの動作を調整する必要があります。次のセクション では、ハードウェア機能をチェックする方法を説明した後、アプリの動作を変更するための アプローチをいくつかご紹介します。

マニフェスト内での機能のフィルタリングと宣言について詳しくは、 uses-feature ガイドをご覧ください。

ハードウェア機能を確認する

Android のフレームワークでは、アプリが実行されているデバイスで ハードウェア機能を使用できるかどうかを判断できます。実行時に特定の機能をチェックするには、hasSystemFeature(String) メソッドを使用します。このメソッドは、チェック対象の機能を指定する因数を 1 つ使用します。

次のコードサンプルでは、実行時にハードウェア機能が利用できるかどうかを検出する方法を示しています 。

Kotlin

// Check whether the telephony hardware feature is available.
if (packageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
    Log.d("HardwareFeatureTest", "Device can make phone calls")
}

// Check whether android.hardware.touchscreen feature is available.
if (packageManager.hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN)) {
    Log.d("HardwareFeatureTest", "Device has a touchscreen.")
}

Java

// Check whether the telephony hardware feature is available.
if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
    Log.d("HardwareFeatureTest", "Device can make phone calls");
}

// Check whether android.hardware.touchscreen feature is available.
if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN)) {
    Log.d("HardwareFeatureTest", "Device has a touchscreen.");
}

タッチスクリーン

ほとんどのテレビデバイスにはタッチスクリーンやポインタ入力機能がなく、ナビゲーションは 矢印ボタン(D-pad)のリモコンに完全に依存しています。テレビアプリは常に D-pad リモコンをサポートする必要があります。

テレビ向けコントロールを使用してナビゲーションを適切にサポートする方法について詳しくは、 テレビ用のナビゲーションをご覧ください。

タッチサポートを宣言する

一部のテレビデバイスはポインタ リモコンとタッチスクリーン ディスプレイをサポートしています。アプリでクリック、 ホバー、スクロール操作をサポートすることで、モバイル デバイスと同様に、これらのデバイス でより快適な操作を提供できます。

アプリでタッチモードを許可する場合は、AndroidManifest.xmlandroid.software.leanback.supports_touchtrue に設定して追加することで、タッチサポートを宣言できます。

<meta-data android:name="android.software.leanback.supports_touch" android:value="true|false"/>

注: ポインタ リモコン(エアマウスやトラックパッドなど)をサポートするデバイスでこれを有効にすると、プラットフォーム互換エミュレーションに依存するのではなく、カーソルモードとタッチモードが有効になります。このメタデータを省略すると、デフォルトで false になります。

カメラ

テレビには通常カメラがありませんが、テレビにカメラ関連 アプリを提供することは可能です。たとえば、写真を撮影、表示、編集する機能があるアプリの場合、テレビ向けに撮影機能を無効にする一方で写真の表示や編集は可能にすることができます。カメラ関連アプリをテレビ向けにする場合は、アプリ マニフェストに次の機能の宣言を追加します。

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

カメラ機能を除いてアプリを動作させる場合は、コードをアプリに追加してカメラ機能が使用可能かどうかを検出し、そのアプリの動作を調整します。次のコードサンプルでは、カメラの存在を検出する方法を示しています。

Kotlin

// Check whether the camera hardware feature is available.
if (packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
    Log.d("Camera test", "Camera available!")
} else {
    Log.d("Camera test", "No camera available. View and edit features only.")
}

Java

// Check whether the camera hardware feature is available.
if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
    Log.d("Camera test", "Camera available!");
} else {
    Log.d("Camera test", "No camera available. View and edit features only.");
}

GPS

テレビは据え付けタイプの室内用デバイスであり、全地球測位システム(GPS) の受信機を内蔵していません。アプリで位置情報が使用されている場合は、ユーザーによる位置情報の検索を許可したり、テレビデバイスのセットアップ時に設定した郵便番号などの静的なロケーション プロバイダを使用したりできます。

Kotlin

// Request a static location from the location manager.
val locationManager = this.getSystemService(Context.LOCATION_SERVICE) as LocationManager
val location: Location = locationManager.getLastKnownLocation("static")

// Attempt to get postal code from the static location object.
val geocoder = Geocoder(this)
val address: Address? =
        try {
            geocoder.getFromLocation(location.latitude, location.longitude, 1)[0]
                    .apply {
                        Log.d(TAG, postalCode)
                    }
        } catch (e: IOException) {
            Log.e(TAG, "Geocoder error", e)
            null
        }

Java

// Request a static location from the location manager.
LocationManager locationManager = (LocationManager) this.getSystemService(
        Context.LOCATION_SERVICE);
Location location = locationManager.getLastKnownLocation("static");

// Attempt to get postal code from the static location object.
Geocoder geocoder = new Geocoder(this);
Address address = null;
try {
  address = geocoder.getFromLocation(location.getLatitude(),
          location.getLongitude(), 1).get(0);
  Log.d("Postal code", address.getPostalCode());

} catch (IOException e) {
  Log.e(TAG, "Geocoder error", e);
}

省電力モードのときに再生を一時停止する

テレビデバイスの中には、ユーザーがデバイスをオフにしたときに省電力モードに切り替わるものがあります。このようなデバイスでは、Android TV はシャットダウンされません。表示は無効になりますが、バックグラウンドでは実行されたままです。省電力モードでもオーディオ出力は引き続き有効なので、省電力モードのときは現在再生されているコンテンツを停止します。

省電力モードのときに再生されないようにするには、onStop() をオーバーライドして現在再生されているコンテンツを停止します。

Kotlin

override fun onStop() {
    // App-specific method to stop playback.
    stopPlayback()
    super.onStop()
}

Java

@Override
public void onStop() {
  // App-specific method to stop playback.
  stopPlayback();
  super.onStop();
}

ユーザーが電源を再度オンにしたときにアプリがフォアグラウンドでアクティブになっている場合は、onStart()が呼び出されます。アクティビティの開始と停止について詳しくは、 アクティビティのライフサイクルをご覧ください。