处理 TV 硬件

TV 硬件与其他 Android 设备截然不同。电视不 包含其他 Android 设备上的一些硬件功能,例如触摸屏、 摄像头和 GPS 接收器此外,电视还完全依赖于辅助硬件设备: 用户必须使用遥控器或游戏手柄才能与 TV 应用互动。(要了解 各种输入法,请参阅管理 TV 控制器)。

在构建 TV 应用时,请仔细考虑应用的硬件限制和要求, 在电视硬件上运行检查您的应用是否正在 TV 上运行,以及标识名是否不受支持 硬件功能。

检查 TV 设备

如果要构建在电视设备和其他设备上运行的应用,您可能需要 查看应用在哪类设备上运行,并调整应用的运行方式。对于 例如,如果您有一个可通过 Intent 启动的应用, 检查设备属性,以确定是否启动面向 TV 的内容 或手机活动

如需确定您的应用是否正在 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");
}

处理不支持的硬件功能

根据应用的设计和功能,您也许能够 硬件功能不可用。本部分讨论了典型的硬件功能 不适用于 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,但在不使用这些功能的情况下也可以运行,请修改应用的清单, 表明这些功能并非必需功能。以下清单代码段 演示了如何声明您的应用不需要不需要的硬件功能 但在非电视设备上使用以下功能:

<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_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 英尺的位置请确保您的界面元素和文字 要求或暗示使用触摸屏。

对于 TV 设备,在设计应用时应使其支持 使用电视遥控器上的方向键进行导航。如需详细了解 正确支持使用 TV 易用型控件进行导航,请参阅 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);
}

在低功耗模式下暂停播放

某些 TV 设备在用户关闭设备时支持低功耗模式。 设备不会关闭,而是会停用显示屏并保留 Android 电视正在后台运行。在此模式下,音频输出仍处于启用状态,因此 在设备处于低功耗模式时停止当前正在播放的任何内容。

如需避免在低功耗模式下播放,请替换 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() 如果您的应用是活跃的前台应用。如需详细了解如何开始和停止 活动,请参阅 <ph type="x-smartling-placeholder"></ph> activity 生命周期