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

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

TV 向けのアプリを作成する場合は、ハードウェアの制限と TV ハードウェアの操作要件を慎重に検討してください。アプリがテレビで実行されているかどうかを確認し、サポートされていないハードウェア機能を処理します。

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

TV デバイスとその他のデバイスの両方で動作するアプリを作成する場合は、アプリが実行されているデバイスの種類を確認し、アプリの動作を調整する必要があります。たとえば、Intent を通じて起動できるアプリがある場合は、デバイス プロパティを確認して、テレビ向けのアクティビティとスマートフォン アクティビティのどちらを開始するかを決定します。

アプリが TV デバイスで動作しているかどうかを判断するには、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

注: 一部の TV コントローラにはマイクが搭載されていますが、ここで説明するマイクのハードウェア機能とは異なります。コントローラのマイクは完全にサポートされています。

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

TV のハードウェア要件を宣言する

Android アプリは、アプリ マニフェストでハードウェア機能の要件を宣言することで、これらの機能を提供していないデバイスにインストールされないようにできます。既存のアプリを TV 用に拡張する場合は、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 受信機がなくても、ユーザーはテレビデバイスにアプリをインストールできます。

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

マニフェストでの機能のフィルタリングと宣言について詳しくは、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 はテレビデバイスのタッチスクリーン操作をサポートしていません。さらに、タッチスクリーンの使用は、ユーザーがディスプレイから 3 メートルほど離れた場所にある視聴環境とは相性が良くありません。UI 要素とテキストがタッチスクリーンの使用を要求または暗示していないことを確認します。

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

カメラ

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

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