處理 TV 硬體

電視硬體與其他 Android 裝置有很大差異。電視不包括其他 Android 裝置上的部分硬體功能,例如觸控螢幕、相機和 GPS 接收器。電視也完全取決於次要硬體裝置:使用者必須使用遙控器或遊戲手把,才能與電視應用程式互動。當您建構電視專用應用程式時,必須仔細考量在電視硬體上運作的硬體限制和要求。

本指南說明如何檢查應用程式是否在電視上執行,以及如何處理不支援的硬體功能。如要瞭解各種輸入法,請參閱管理電視控制器

檢查電視裝置

如要建構同時適用於電視裝置和其他裝置的應用程式,您可能需要檢查應用程式執行的裝置類型,並調整應用程式的運作。舉例來說,如果您的應用程式可以透過 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 應用程式可以在應用程式資訊清單中宣告硬體功能需求,確保應用程式沒有安裝在不支援這些功能的裝置上。如果您要將現有應用程式擴充為在電視上使用,請仔細檢查應用程式資訊清單,確認是否有任何硬體要求宣告可能導致電視裝置無法安裝該應用程式。

如果您的應用程式使用了電視不支援的硬體功能 (例如觸控螢幕或相機),但可以在不使用這類功能的情況下運作,請修改應用程式的資訊清單,指出這類功能不需要使用。下列資訊清單程式碼片段說明如何宣告應用程式不需要電視裝置所沒有的硬體功能,但在非 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 應用程式」中所述,所有適用於電視裝置的應用程式都必須聲明不需要觸控螢幕功能。如果應用程式通常會使用電視裝置不支援的一或多項功能,請將資訊清單中的 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_LOCATIONACCESS_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 不支援透過電視裝置進行觸控螢幕互動。此外,在使用者與螢幕相距 10 英尺遠的地方使用觸控螢幕與觀看環境不同。請確保 UI 元素和文字不需要或暗示使用觸控螢幕。

針對電視裝置,請將應用程式設計成支援使用電視遙控器上的方向鍵 (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) 接收器。如果您的應用程式使用位置資訊,您仍可讓使用者搜尋地點或使用靜態位置供應商,例如電視裝置設定期間設定的郵遞區號。

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()。如要進一步瞭解如何啟動及停止活動,請參閱「 活動生命週期」。