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

テレビのハードウェアは、他の Android デバイスとは大きく異なります。TV には、タッチスクリーン、カメラ、GPS レシーバーなど、他の Android デバイスに搭載されているハードウェア機能の一部は含まれていません。また、TV はセカンダリ ハードウェア デバイスに完全に依存します。ユーザーが TV アプリを操作する際は、リモコンまたはゲームパッドを使用する必要があります。TV 向けアプリを作成する場合は、ハードウェアの制限と TV ハードウェアの操作に関する要件を慎重に検討する必要があります。

このガイドでは、アプリがテレビで実行されているかどうかを確認する方法と、サポートされていないハードウェア機能を処理する方法について説明します。さまざまな入力方法については、TV コントローラを管理するをご覧ください。

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

テレビデバイスと他のデバイスの両方で動作するアプリを作成する場合は、アプリが動作するデバイスの種類を確認し、アプリの動作を調整する必要があります。たとえば、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");
}

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

アプリのデザインと機能によっては、特定のハードウェア機能が利用できないことを回避できる場合があります。このセクションでは、通常 TV で使用できないハードウェア機能、不足しているハードウェア機能を検出する方法、それらの機能に代わるものについて説明します。

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

TV は他のデバイスとは目的が異なるため、他の Android 搭載デバイスのようなハードウェア機能は備えていません。そのため Android システムは、TV デバイスで以下の機能をサポートしていません。

ハードウェア 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 アプリは、アプリ マニフェストでハードウェア機能の要件を宣言することで、そのような機能を備えていないデバイスにインストールされないようにすることができます。既存のアプリをテレビ用に拡張する場合は、アプリのマニフェストで、テレビデバイスへのインストールを妨げる可能性のあるハードウェア要件の宣言がないか十分に確認してください。

タッチスクリーンやカメラなど、TV では使用できないハードウェア機能をアプリが使用していて、そのような機能を使用せずに動作できる場合は、アプリのマニフェストを変更して、そのような機能が必須でないことを示すようにしてください。次のマニフェスト コード スニペットは、TV デバイスでは利用できないハードウェア機能をアプリが必要とせず、TV 以外のデバイスではその機能を使用することを宣言する方法を示しています。

<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" としてマークしてください。

TV アプリのスタートガイドに記載されているとおり、TV デバイスで使用するすべてのアプリでは、タッチスクリーン機能が不要であることを宣言する必要があります。TV デバイスでサポートされていない機能をアプリが通常使用している場合は、マニフェストでその機能の android:required 属性設定を false に変更します。

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

ハードウェア機能を暗黙的に示唆する権限に注意する

uses-permission マニフェストの一部の宣言は、ハードウェア機能を暗示するものです。つまり、アプリ マニフェストで一部の権限をリクエストすることで、アプリが TV デバイスにインストールされず、使用されなくなる可能性があります。一般にリクエストされる次の権限により、暗黙的なハードウェア機能の要件が作成されます。

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 レシーバーがない場合でも、TV デバイスにアプリをインストールできます。

アプリのハードウェア機能をオプションにしたら、実行時にそれらの機能が利用できることを確認してから、アプリの動作を調整する必要があります。次のセクションでは、ハードウェア機能をチェックする方法と、アプリの動作を変更する方法をいくつか提案します。

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

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

Android フレームワークは、アプリを実行しているデバイスでハードウェア機能が利用できないかどうかを通知します。実行時に特定の機能を確認するには、hasSystemFeature(String) メソッドを使用します。このメソッドは、チェックする機能を指定する単一の文字列引数を取ります。

次のコードサンプルは、実行時にハードウェア機能の可用性を検出する方法を示しています。

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.");
}

タッチスクリーン

ほとんどのテレビにはタッチスクリーンがないため、Android は TV デバイスでのタッチスクリーン操作をサポートしていません。さらに、タッチスクリーンの使用は、ユーザーが 10 フィート離れた場所から座る視聴環境とは一貫性がありません。UI 要素とテキストが、タッチスクリーンの使用を必要としない、または暗示していないことを確認してください。

TV デバイスの場合は、TV リモコンの十字キー(D-pad)を使用してナビゲーションをサポートするようにアプリを設計します。テレビに適したコントロールを使用してナビゲーションを適切にサポートする方法については、テレビのナビゲーションをご覧ください。

カメラ

通常、テレビにカメラはありませんが、写真関連のアプリをテレビで提供することは可能です。たとえば、写真の撮影、表示、編集を行うアプリの場合は、テレビ用の写真撮影機能を無効にしても、ユーザーは写真を表示、編集することができます。カメラ関連アプリをテレビで動作するようにする場合は、アプリ マニフェストに次の機能の宣言を追加します。

<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)レシーバーを内蔵していません。アプリで位置情報を使用する場合でも、ユーザーに場所の検索を許可したり、TV デバイスのセットアップ時に設定した郵便番号などの静的な位置情報プロバイダを使用したりすることは可能です。

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() が呼び出されます。アクティビティの開始と停止の詳細については、 アクティビティのライフサイクルをご覧ください。