處理 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

注意:部分電視控制器配有麥克風,但與這裡所述的麥克風硬體功能說明不同。完整支援控制器麥克風。

如需功能、子功能及其描述元的完整清單,請參閱 功能參考資料。

宣告 TV 的硬體需求

Android 應用程式可以在應用程式資訊清單中宣告硬體功能需求,確保不會安裝在未提供這些功能的裝置上。如果您要擴充現有應用程式,以便在電視上使用,請仔細檢查應用程式資訊清單,確認是否有任何硬體需求宣告,可能會導致應用程式無法安裝在電視裝置上。

如果應用程式使用電視不支援的硬體功能 (例如觸控螢幕或相機),但即使不使用這些功能也能運作,請修改應用程式的資訊清單,指出這些功能並非必要。下列資訊清單程式碼片段說明如何宣告應用程式不需要電視裝置不支援的硬體功能,但會在非電視裝置上使用這些功能:

<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,宣告為必要功能,應用程式就無法安裝在電視裝置上,也不會顯示在 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 權限,即使電視裝置沒有網路卡或 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.");
}

觸控螢幕

大多數電視裝置都沒有觸控螢幕或指標輸入功能,完全仰賴方向鍵 (D-pad) 遙控器進行操作。電視應用程式一律必須支援 D-pad 遙控器。

如要進一步瞭解如何使用適合電視的控制項正確支援導覽功能,請參閱「電視導覽」。

宣告觸控支援

部分電視裝置支援指標遙控器和觸控螢幕。您的應用程式可以支援點擊、懸停和捲動互動,就像在行動裝置上一樣,在支援這些互動的裝置上提供更優質的體驗。

如果應用程式允許觸控模式,您可以在 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。

相機

雖然電視通常沒有相機,但您仍可在電視上提供攝影相關應用程式。舉例來說,如果應用程式可拍攝、查看及編輯相片,您可以停用電視的拍照功能,但仍允許使用者查看甚至編輯相片。如果您決定讓相機相關應用程式在電視上運作,請在應用程式資訊清單中加入下列功能宣告:

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