O hardware de TV é substancialmente diferente de outros dispositivos Android. As TVs não incluem alguns dos recursos de hardware encontrados em outros dispositivos Android, como touchscreens, câmeras e receptores de GPS. As TVs também são completamente dependentes de dispositivos de hardware secundários: para que os usuários interajam com apps de TV, é preciso usar um controle remoto ou um controlador de jogo. Para saber mais sobre vários métodos de entrada, consulte Gerenciar controladores de TV.
Ao criar um app para TV, considere cuidadosamente as limitações e os requisitos de hardware para a operação em hardwares de TV. Verifique se o app está sendo executado em uma TV e lide com recursos de hardware incompatíveis.
Verificar se há um dispositivo de TV
Se você está criando um app que opere tanto em dispositivos de TV quanto em outros dispositivos, pode ser necessário verificar em que tipo de dispositivo seu app está sendo executado e ajustar a operação. Por exemplo, se você tem um app que pode ser iniciado por uma Intent, verifique as propriedades do dispositivo para determinar se inicia uma atividade voltada à TV ou a um smartphone.
O modo recomendado para determinar se o app está sendo executado em um dispositivo de TV é usar o método PackageManager.hasSystemFeature() para verificar se o dispositivo está sendo executado no modo televisão. A amostra de código a seguir mostra como verificar se
o app está sendo executado em um 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"); }
Lidar com recursos de hardware incompatíveis
Dependendo do projeto e da funcionalidade do app, você pode ignorar determinados recursos de hardware indisponíveis. Esta seção discute que recursos de hardware não estão normalmente disponíveis para TV, como detectar recursos de hardware ausentes e quais alternativas são sugeridas para esses recursos.
Recursos de hardware de TV incompatíveis
As TVs têm uma finalidade diferente de outros dispositivos e, por isso, não têm recursos de hardware que outros dispositivos Android frequentemente têm. Por essa razão, o sistema Android não oferece compatibilidade com os seguintes recursos para um dispositivo de TV:
| Hardware | Descritor de recurso do Android |
|---|---|
| Touchscreen | android.hardware.touchscreen |
| Emulador de touchscreen | android.hardware.faketouch |
| Telefonia | android.hardware.telephony |
| Câmera | android.hardware.camera |
| Comunicação a curta distância (NFC) | android.hardware.nfc |
| GPS | android.hardware.location.gps |
| Microfone | android.hardware.microphone |
| Sensores | android.hardware.sensor |
| Tela na orientação retrato | android.hardware.screen.portrait |
Observação:alguns controladores de TV têm um microfone diferente do recurso de hardware de microfone descrito aqui. O microfone do controle é totalmente compatível.
Consulte a Referência de recursos para uma lista completa de recursos, sub-recursos e descritores.
Declarar requisitos de hardware para TV
Os apps Android podem declarar requisitos de recursos de hardware no manifesto do app para garantir que eles não sejam instalados em dispositivos que não ofereçam esses recursos. Se estiver estendendo um app existente para uso em TVs, revise cuidadosamente o manifesto do app para detectar qualquer declaração de requisito de hardware que possa evitar que o app seja instalado em um dispositivo de TV.
Se o app usa recursos de hardware, como uma touchscreen ou câmera, que não estão disponíveis na TV, mas pode operar sem o uso desses recursos, modifique o manifesto para indicar que eles não são necessários. O snippet de código de manifesto a seguir demonstra como declarar que o app não exige recursos de hardware indisponíveis em dispositivos de TV, mas usa esses recursos em outros tipos de dispositivo:
<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"/>
Observação:alguns recursos têm sub-recursos, como android.hardware.camera.front, conforme descrito na
Referência de recursos. Marque todos os subrecursos que também são usados no seu app como required="false".
Todos os apps previstos para uso em dispositivos de TV precisam declarar que o recurso de touchscreen não é necessário, como descrito em Introdução a apps para TV. Se o app usa normalmente um ou mais recursos indisponíveis com dispositivos de TV, altere a configuração do atributo android:required para false para esses recursos no manifesto.
Cuidado:declarar um recurso de hardware como obrigatório definindo o valor dele como true evita que o app seja instalado em dispositivos de TV ou apareça na tela inicial do Android TV.
Conheça as permissões que exigem recursos de hardware
Algumas declarações de manifesto uses-permission implicam recursos de hardware. Esse comportamento significa que a solicitação de permissões no manifesto do app pode impedir que o app seja instalado e usado em dispositivos de TV. As seguintes permissões normalmente solicitadas criam uma exigência implícita de recurso de hardware:
| Permissão | Recurso de hardware afetado |
|---|---|
RECORD_AUDIO |
android.hardware.microphone |
CAMERA |
android.hardware.camera e android.hardware.camera.autofocus |
ACCESS_COARSE_LOCATION |
|
ACCESS_FINE_LOCATION |
|
ACCESS_WIFI_STATECHANGE_WIFI_STATE
|
Algumas TVs têm apenas uma conexão Ethernet. |
Para ver uma lista completa de solicitações de permissão que implicam uma exigência de recurso de hardware, consulte o guia de uses-feature. Se o app exigir um dos recursos listados acima, inclua uma declaração uses-feature no manifesto para o recurso de hardware implícito que indique que ele não é obrigatório. android:required="false".
Observação:se o app for destinado ao Android 5.0 (nível da API 21) ou mais recente e usar a permissão ACCESS_COARSE_LOCATION ou ACCESS_FINE_LOCATION, os usuários ainda poderão fazer a instalação em um dispositivo de TV, mesmo que não haja uma placa de rede ou um receptor de GPS.
Depois de tornar os recursos de hardware opcionais para o app, é preciso verificar a disponibilidade deles no tempo de execução e ajustar o comportamento do app. A seção seguinte discute como verificar os recursos de hardware e sugere algumas abordagens para mudar o comportamento do seu app.
Para mais informações sobre como filtrar e declarar recursos no manifesto, consulte o guia uses-feature.
Verificar se há recursos de hardware
O framework do Android pode informar se os recursos de hardware não estão disponíveis no dispositivo em que o app está sendo executado. Use o método hasSystemFeature(String)
para conferir recursos específicos no tempo de execução. Esse método usa um argumento de string único que especifica o recurso que você quer verificar.
O exemplo de código a seguir demonstra como detectar a disponibilidade de recursos de hardware no tempo de execução:
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."); }
Tela touchscreen
A maioria dos dispositivos de TV não tem telas touchscreen nem recursos de entrada de ponteiro e depende totalmente de controles remotos com teclado direcional (D-pad) para navegação. Os apps de TV precisam sempre oferecer suporte a um controle remoto com botão direcional.
Para mais informações sobre como oferecer a compatibilidade adequada à navegação usando controles compatíveis com TV, consulte Navegação na TV.
Declarar compatibilidade com toque
Alguns dispositivos de TV são compatíveis com controles remotos com ponteiro e telas sensíveis ao toque. Seu app pode oferecer suporte a interações de clique, passar o cursor e rolagem, como em um dispositivo móvel, para proporcionar uma experiência melhor em dispositivos que oferecem suporte a elas.
Se o app permitir o modo de toque, declare o suporte a esse modo adicionando android.software.leanback.supports_touch como definido como true no AndroidManifest.xml:
<meta-data android:name="android.software.leanback.supports_touch" android:value="true|false"/>
Observação: em dispositivos que oferecem suporte a um controle remoto de apontamento (como um mouse aéreo ou um trackpad), a ativação desse recurso
ativa o modo de cursor e toque em vez de depender da emulação de compatibilidade da plataforma. Se você omitir esses metadados, o padrão será false.
Câmera
Apesar de uma TV normalmente não ter uma câmera, você pode oferecer um app relacionado a fotografia a um dispositivo de TV. Por exemplo, se você tem um app que tira, exibe e edita fotos, poderá desativar a funcionalidade de tirar fotos para TVs e ainda permitir que os usuários visualizem e até mesmo editem fotografias. Se decidir permitir que o app relacionado a câmeras funcione em uma TV, adicione a seguinte declaração de recurso ao manifesto do app:
<uses-feature android:name="android.hardware.camera" android:required="false" />
Se você permitir que o app funcione sem uma câmera, adicione um código que detecte se o recurso da câmera está disponível e faça ajustes à operação do app. O exemplo a seguir demonstra como detectar a presença de uma câmera:
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
As TVs são dispositivos estacionários para interiores e não têm um receptor de sistema de posicionamento global (GPS) integrado. Se o app usa informações de localização, você pode permitir que usuários pesquisem um local ou usem um provedor de localização estática, como um CEP definido durante a configuração do dispositivo.
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); }
Pausar a reprodução no modo de baixo consumo de energia
Alguns dispositivos de TV oferecem um modo de baixo consumo de energia quando o usuário desliga o dispositivo. Em vez de desligar, o dispositivo desativa a tela e mantém o Android TV funcionando em segundo plano. Nesse modo, a saída de áudio permanece ativada, então interrompa qualquer conteúdo em reprodução quando o dispositivo entra no modo de baixo consumo de energia.
Para evitar reproduções durante o modo de baixo consumo de energia, substitua
onStop()
e interrompa qualquer conteúdo em reprodução:
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(); }
Quando o usuário liga o dispositivo novamente, onStart() é chamado
se o aplicativo for o aplicativo ativo em primeiro plano. Para mais informações sobre como iniciar e interromper
uma atividade, consulte
O ciclo de vida da atividade.