El hardware de TV es muy diferente de otros dispositivos Android. Las TV no incluyen algunas de las funciones de hardware que se encuentran en otros dispositivos Android, como pantallas táctiles, cámaras y receptores de GPS. Las TV también dependen por completo de dispositivos de hardware secundarios: para que los usuarios puedan interactuar con aplicaciones para TV, deben usar un control remoto o un controlador para juegos. (Para obtener información sobre los distintos métodos de entrada, consulta Cómo administrar controladores de TV).
Cuando compiles una app para TV, presta mucha atención a las limitaciones y a los requisitos de hardware para que pueda funcionar en hardware de TV. Comprueba si tu app se ejecuta en una TV y controla las funciones de hardware no compatibles.
Cómo buscar un dispositivo de TV
Si vas a compilar una app que funciona tanto en TV como en otros dispositivos, es posible que necesites
comprobar en qué tipo de dispositivo se está ejecutando para modificar cómo debe operar. Por
ejemplo, si tienes una app que puede iniciarse a través de un Intent,
comprueba las propiedades del dispositivo para determinar si debe iniciar una actividad orientada a TV
o a teléfono.
La práctica recomendada para determinar si tu app se ejecuta en un dispositivo de TV es usar el método PackageManager.hasSystemFeature() para verificar
si el dispositivo se ejecuta en modo de TV. En el siguiente código de ejemplo, se muestra cómo comprobar si
tu app se ejecuta en un dispositivo de 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"); }
Cómo manejar las funciones de hardware no compatibles
Según el diseño y la funcionalidad de tu app, es posible que puedas evitar el problema de que ciertas funciones de hardware no estén disponibles. En esta sección, se explica cuáles son las funciones de hardware que no suelen estar disponibles para TV, cómo detectar funciones de hardware faltantes y qué alternativas se sugieren para estas funciones.
Funciones no compatibles para hardware de TV
Las TV tienen un propósito diferente al de otros dispositivos y, por lo tanto, no suelen tener las mismas funciones de hardware que otros dispositivos Android. Por este motivo, el sistema Android no admite las siguientes funciones para un dispositivo de TV:
| Hardware | Descriptor de funciones de Android |
|---|---|
| Pantalla táctil | android.hardware.touchscreen |
| Emulador de pantalla táctil | android.hardware.faketouch |
| Telefonía | android.hardware.telephony |
| Cámara | android.hardware.camera |
| Comunicación de campo cercano (NFC) | android.hardware.nfc |
| GPS | android.hardware.location.gps |
| Micrófono | android.hardware.microphone |
| Sensores | android.hardware.sensor |
| Pantalla en orientación vertical | android.hardware.screen.portrait |
Nota: Algunos controladores de TV tienen un micrófono, que no es el mismo que el de la función de hardware de micrófono que se describe aquí. El micrófono del controlador es completamente compatible.
Consulta la Referencia de funciones para obtener una lista completa de las funciones, las subfunciones y sus descriptores.
Cómo declarar requisitos de hardware para TV
Las apps de Android pueden declarar requisitos de funciones de hardware en el manifiesto de la app para garantizar que no se instalen en dispositivos que no poseen tales funciones. Si quieres expandir una app existente para que se use en TV, busca en el manifiesto de tu app declaraciones de requisitos de hardware que puedan impedir que se instale en un dispositivo de TV.
Si tu app usa funciones de hardware (como una pantalla táctil o cámara) que no están disponibles en una TV, pero puede funcionar sin ellas, deberás modificar el manifiesto de tu app para indicar que no requiere estas funciones. En el siguiente fragmento de código de manifiesto se muestra cómo declarar que tu app no requiere funciones de hardware que no están disponibles en dispositivos de TV, a pesar de que puede usarlas en otros tipos de dispositivos:
<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"/>
Nota: Algunas funciones tienen subfunciones como android.hardware.camera.front, tal como se describe en
Referencia de funciones. Asegúrate de marcar como required="false" las subfunciones que también se usan en tu app.
Todas las apps creadas para usarse en dispositivos de TV deben declarar que la función de pantalla táctil no es obligatoria,
como se describe en Cómo comenzar con
apps para TV. Si tu app normalmente usa una o más de las funciones no compatibles con dispositivos de TV, cambia la
android:required configuración del atributo a false para esas funciones en tu manifiesto.
Precaución: Si declaras una función de hardware mediante la definición de su
valor en true evitarás que tu app se instale en dispositivos de TV
o que aparezca en el selector de la pantalla principal de Android TV.
Ten en cuenta los permisos que implican funciones de hardware
Algunas uses-permission
declaraciones del manifiesto implican funciones de hardware. Este comportamiento supone que solicitar ciertos
permisos en el manifiesto de la app puede impedir que esta se instale y use en dispositivos de TV. Los siguientes permisos comúnmente solicitados crean un requisito implícito de funciones de hardware
requisito:
| Permiso | Función implícita de hardware |
|---|---|
RECORD_AUDIO |
android.hardware.microphone |
CAMERA |
android.hardware.camera y android.hardware.camera.autofocus |
ACCESS_COARSE_LOCATION |
|
ACCESS_FINE_LOCATION |
|
ACCESS_WIFI_STATECHANGE_WIFI_STATE
|
Algunos dispositivos de TV solo tienen una conexión Ethernet. |
Para obtener una lista completa de solicitudes de permisos que suponen un requisito de función implícita de hardware, consulta la
uses-feature
guía. Si tu app solicita una de las funciones mencionadas anteriormente, deberás incluir una
uses-feature
declaración en tu manifiesto para la función de hardware implícita que indique que no es
obligatoria. android:required="false".
Nota: Si tu app se orienta a Android 5.0 (nivel de API 21) o
versiones posteriores, y usa el permiso ACCESS_COARSE_LOCATION o
ACCESS_FINE_LOCATION, los usuarios igualmente pueden instalar tu
app en un dispositivo de TV, incluso si este no tiene una tarjeta de red o un receptor de GPS.
Si decides que las funciones de hardware son opcionales para tu app, deberás comprobar la disponibilidad de aquellas funciones durante el tiempo de ejecución y, luego, ajustar el comportamiento de tu app. En la siguiente sección se explica cómo buscar funciones de hardware y se sugieren algunos enfoques para cambiar el comportamiento de tu app.
Para obtener más información sobre cómo filtrar y declarar funciones en el manifiesto, consulta la
uses-feature
guía.
Cómo buscar funciones de hardware
El marco de trabajo de Android puede indicarte si hay funciones de hardware no disponibles en el dispositivo en el que
se ejecuta tu app. Utiliza el método hasSystemFeature(String)
para comprobar funciones específicas en el tiempo de ejecución. Este método toma un único argumento de string que
especifica la función que quieres buscar.
En siguiente ejemplo de código, se muestra cómo detectar la disponibilidad de funciones de hardware durante el tiempo de ejecución:
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."); }
Pantalla táctil
La mayoría de los dispositivos de TV no tienen pantallas táctiles ni capacidades de entrada de puntero, y dependen por completo de los controles remotos de pad direccional (pad direccional) para la navegación. Las apps para TV siempre deben admitir un control remoto de pad direccional.
Para obtener más información sobre cómo admitir la navegación mediante controles compatibles con la TV, consulta Navegación para TV.
Cómo declarar la compatibilidad táctil
Algunos dispositivos de TV admiten controles remotos de puntero y pantallas táctiles. Tu app puede admitir interacciones de clic, desplazamiento del cursor y desplazamiento, como en un dispositivo móvil, para proporcionar una mejor experiencia en dispositivos que las admitan.
Si tu app permite el modo táctil, puedes declarar la compatibilidad táctil agregando android.software.leanback.supports_touch como true en tu AndroidManifest.xml:
<meta-data android:name="android.software.leanback.supports_touch" android:value="true|false"/>
Nota: En dispositivos que admiten un control remoto de puntero (como un mouse inalámbrico o una superficie táctil), habilitar esta opción
habilita el cursor y el modo táctil en lugar de depender de la emulación de compatibilidad de la plataforma. Si se omite
este metadato, el valor predeterminado es false.
Cámara
Si bien las TV no suelen tener cámara, puedes proporcionar una app relacionada con la fotografía en una TV. Por ejemplo, si tienes una app cuya función es tomar, ver y editar fotos, puedes inhabilitar la funcionalidad de toma de fotos para la TV, pero permitir que los usuarios las vean y editen fotos. Si decides permitir que tu app relacionada con la cámara funcione en una TV, agrega la siguiente declaración de función en el manifiesto de tu app:
<uses-feature android:name="android.hardware.camera" android:required="false" />
Si permites que tu app se ejecute sin una cámara, deberás agregarle código para que detecte si la función de cámara está disponible y ajustar el funcionamiento de tu app. En el siguiente ejemplo de código, se muestra cómo detectar la presencia de una cámara:
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
Las TV son dispositivos fijos, de interior y no tienen receptores integrados de sistema de posicionamiento global (GPS) Si tu app usa información de ubicación, igualmente puedes permitir que los usuarios busquen una ubicación o usen un proveedor de ubicación estática, como un código postal que se ingresa durante la configuración inicial de dispositivo de TV.
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); }
Cómo pausar la reproducción durante el modo de bajo consumo
Algunos dispositivos de TV admiten el modo de bajo consumo cuando el usuario apaga el dispositivo. En lugar de apagarse, el dispositivo inhabilita la pantalla y sigue ejecutando Android TV en segundo plano. La salida de audio permanece habilitada en este modo, por lo que debes detener cualquier contenido que se esté reproduciendo cuando se activa el modo de bajo consumo.
Para evitar que se reproduzca contenido durante el modo de bajo consumo, debes anular la función onStop() y detener la reproducción:
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(); }
Cuando el usuario vuelva a encenderlo, se llamará a onStart()
si tu app es la app en primer plano activa. Para obtener más información sobre cómo iniciar y detener
una actividad, consulta
El ciclo de vida de la actividad.