處理 TV 硬體

電視硬體與其他 Android 裝置有很大的差異。電視不包含其他 Android 裝置上的部分硬體功能,例如觸控螢幕、相機和 GPS 接收器。電視也完全依賴次要硬體裝置:如要與電視應用程式互動,他們必須使用遙控器或遊戲手把。(如要瞭解各種輸入法,請參閱「管理電視遙控器」)。

建構 Android 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");
}

處理不支援的硬體功能

視應用程式的設計和功能而定,您或許可以排除無法使用的特定硬體功能。本節說明通常電視無法使用的硬體功能、如何偵測缺少的硬體功能,以及這些功能的建議替代方案。

不支援的電視硬體功能

電視的用途與其他裝置不同,因此不具備其他 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 使用,請仔細檢查應用程式資訊清單,找出可能導致應用程式無法安裝到 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 裝置上使用。下列要求的權限經常建立隱性硬體功能需求:

權限 隱含硬體功能
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()。如要進一步瞭解如何啟動和停止活動,請參閱「 活動生命週期」。