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

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

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

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

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

アプリが TV デバイスで実行されているかどうかを判断するには、PackageManager.hasSystemFeature メソッドを使用して、デバイスがテレビモードで実行されているかどうかを確認することをおすすめします。次のサンプルコードは、アプリが TV デバイスで実行されているかどうかを確認する方法を示しています。

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

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

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

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

Android アプリは、アプリ マニフェストでハードウェア機能の要件を宣言することで、それらの機能を提供しないデバイスにインストールされないようにすることができます。既存のアプリを拡張して 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 デバイスでサポートされていない機能を 1 つ以上使用している場合は、マニフェストでそれらの機能の android:required 属性設定を false に変更します。

注意: ハードウェア機能の値を true に設定して必須として宣言すると、アプリを TV デバイスにインストールしたり、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 権限を使用する場合、TV デバイスにネットワーク カードや 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.");
}

タッチスクリーン

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

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

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

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

アプリでタッチモードを許可する場合は、AndroidManifest.xml の <application> 要素または <activity> 要素内に、true に設定された android.software.leanback.supports_touch <property> 要素を追加することで、アプリ全体または個々のアクティビティでタッチサポートを宣言できます。

<application ...>
    <property
        android:name="android.software.leanback.supports_touch"
        android:value="true|false" />
    ...
</application>

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

カメラ

通常、テレビにはカメラが搭載されていませんが、テレビで写真関連のアプリを提供することは可能です。たとえば、写真の撮影、表示、編集を行うアプリがある場合、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 = locationManager.getLastKnownLocation("static")
if (location == null) {
    Log.e(TAG, "Location is null")
    return
}

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