Gerenciar controles de TV

Os dispositivos de TV exigem um dispositivo de hardware secundário para interagir com apps: um controle remoto básico, um controle remoto com ponteiro ou um controle de jogo. Para oferecer uma experiência do usuário consistente, seu app precisa aceitar entrada por botão direcional, lidar com controles que ficam off-line e aceitar entrada de vários tipos de controle, incluindo controles remotos de ponteiro.

Controles D-pad mínimos

O controlador padrão para um dispositivo de TV é um D-pad. Em geral, o app precisa ser operável por um controle remoto que tenha apenas os botões para cima, para baixo, para a esquerda, para a direita, selecionar, "Voltar" e "Início". Se o app for um jogo que normalmente exige um controle com mais botões, tente oferecer suporte à jogabilidade apenas com esses botões direcionais. Caso contrário, avise o usuário que um controle é necessário e permita que ele saia do jogo normalmente usando o botão direcional.

Para mais informações sobre a navegação com botões direcionais em dispositivos de TV, consulte Navegação na TV.

Tratar desconexões do controlador

Os controles para TV costumam ser dispositivos Bluetooth, que podem tentar economizar energia entrando periodicamente no modo de espera e se desconectando do dispositivo de TV. Isso significa que um app pode ser interrompido ou reiniciado se não estiver configurado para lidar com esses eventos de reconexão. Esses eventos podem acontecer em qualquer uma das seguintes circunstâncias:

  • Enquanto um vídeo de vários minutos é reproduzido, um botão direcional ou controle de jogo pode entrar no modo de espera, se desconectar do dispositivo de TV e se reconectar mais tarde.
  • Durante o jogo, um novo jogador pode entrar usando um controle de jogo que ainda não está conectado.
  • Durante o jogo, um jogador pode sair do jogo e desconectar um controle de jogo.

Qualquer atividade do app de TV que esteja sujeita a eventos de desconexão e reconexão precisa ser configurada para processar eventos de reconexão no manifesto do app. O exemplo de código a seguir demonstra como permitir que uma atividade processe mudanças de configuração, incluindo a conexão, desconexão ou reconexão de um teclado ou dispositivo de navegação:

<activity
  android:name="com.example.android.TvActivity"
  android:label="@string/app_name"
  android:configChanges="keyboard|keyboardHidden|navigation"
  android:theme="@style/Theme.Leanback">

  <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LEANBACK_LAUNCHER" />
  </intent-filter>
  ...
</activity>

Essa mudança de configuração permite que o app continue em execução durante um evento de reconexão, em vez de ser reiniciado pelo framework do Android, o que não é uma boa experiência do usuário.

Gerenciar variações de entradas do D-pad

Os usuários de dispositivos de TV podem ter mais de um tipo de controle para usar com a TV. Por exemplo, um usuário pode ter um controle básico com botão direcional, um controle remoto com ponteiro ou um controle de jogo. Os códigos de tecla fornecidos por um controle de jogo quando ele é usado para funções de botão direcional podem variar em relação aos códigos de tecla enviados por um botão direcional básico.

Gerencie as variações na entrada do botão direcional para que o usuário não precise trocar de controle para operar o app. Para mais informações sobre como gerenciar variações de entrada, consulte Processar entrada do botão direcional.

Suporte a controles remotos com ponteiro

Alguns dispositivos de TV são compatíveis com controles remotos de ponteiro, como mouses aéreos ou controles remotos com direcionais sensíveis ao toque (trackpads). Com o suporte a controles remotos de ponteiro, os usuários podem interagir com o app usando gestos de apontar e clicar, passar o cursor, deslizar e arrastar, proporcionando uma experiência mais fluida em hardware compatível e mantendo a compatibilidade total com o botão direcional.

Declarar suporte ao controle remoto no manifesto

Para indicar que o app é navegável com entrada por ponteiro e toque, configure o manifesto do app com o android.software.leanback.supports_touch <property> definido como true dentro do elemento <application> (ou dentro de elementos <activity> individuais para configurar o suporte por atividade):

<manifest ...>
    <!-- Signal whether the app is adaptive or built just for TV -->
    <uses-feature
        android:name="android.software.leanback"
        android:required="true|false" />
    <!-- Ensure the app can be installed on conventional TVs -->
    <uses-feature
        android:name="android.hardware.touchscreen"
        android:required="false" />
    <application ...>
        <!-- Signal whether the app supports pointer remotes -->
        <property
            android:name="android.software.leanback.supports_touch"
            android:value="true" />
        ...
    </application>
</manifest>

Suporte a interações de clique, passagem do cursor e rolagem

Ao oferecer suporte a controles remotos de ponteiro, verifique se os componentes da interface respondem adequadamente à entrada por toque e ao cursor nas seguintes interações:

  • Clique e seleção: todos os elementos da interface que podem ser selecionados e focados precisam ser clicáveis com o controle remoto de ponteiro, correspondendo ao comportamento da seleção do botão direcional (KEYCODE_DPAD_CENTER).
  • Estados visuais de passagem do cursor: forneça um efeito visual claro para indicar quando o cursor está posicionado sobre um item selecionável.
  • Rolagem por deslize e toque rápido: a rolagem horizontal e vertical acionada por um gesto de deslize ou toque rápido em um botão direcional central sensível ao toque precisa funcionar sem problemas em todo o conteúdo rolável.
  • Rolagem por arrasto: os usuários precisam conseguir arrastar para rolar verticalmente (para cima e para baixo) ou horizontalmente (para a esquerda e para a direita) em contêineres roláveis.
    • Jetpack Compose: os contêineres roláveis padrão são compatíveis com a rolagem por ponteiro e toque por padrão. Para implementações personalizadas, consulte Entrada de ponteiro no Compose.
    • Visualizações: as visualizações roláveis padrão oferecem suporte à rolagem por toque por padrão. Para processamento de entrada personalizado, consulte Toque e entrada.
  • Arrastar a barra de busca de mídia: durante a reprodução de mídia (como séries de TV e filmes), os usuários precisam conseguir interagir com a barra de progresso da reprodução (barra de busca) apontando e clicando para pular para um carimbo de data/hora anterior ou posterior, além de arrastar (fazer o scrubbing) ao longo da barra de progresso para buscar um horário específico.

Gerenciar eventos de botão

Quando o usuário clica em um botão em um controle, seu app recebe um evento com um KeyEvent. O comportamento pretendido para o botão pode ser um evento de mídia, como reproduzir, pausar ou parar, ou um evento do tipo TV, como seleção ou navegação. Para oferecer uma boa experiência ao usuário, atribua um comportamento consistente aos botões do controle.

Eventos de IU da TV

Atribua o comportamento da interface de TV aos botões que geram tipos KeyEvent, conforme mostrado na tabela a seguir:

KeyEvent Comportamento
KEYCODE_BUTTON_B, KEYCODE_BACK Voltar
KEYCODE_BUTTON_SELECT, KEYCODE_BUTTON_A, KEYCODE_ENTER, KEYCODE_DPAD_CENTER, KEYCODE_NUMPAD_ENTER Seleção
KEYCODE_DPAD_UP, KEYCODE_DPAD_DOWN, KEYCODE_DPAD_LEFT, KEYCODE_DPAD_RIGHT Navegação

Eventos de mídia

Quando o usuário estiver assistindo mídia, atribua comportamento aos botões que geram tipos de KeyEvent, conforme mostrado na tabela a seguir. Se o app estiver controlando um MediaSession, use um MediaControllerAdapter para chamar um dos métodos MediaControllerCompat.TransportControls mostrados na tabela. Os botões de seleção funcionam como botões de reprodução ou pausa nesse contexto.

KeyEvent Chamada TransportControls Comportamento
BUTTON_SELECT, BUTTON_A, ENTER, DPAD_CENTER, KEYCODE_NUMPAD_ENTER play() Reproduzir
BUTTON_START, BUTTON_SELECT, BUTTON_A, ENTER, DPAD_CENTER, KEYCODE_NUMPAD_ENTER pause() Pausar
BUTTON_R1 skipToNext() Pular para a próxima
BUTTON_L1 skipToPrevious() Pular para a anterior
DPAD_RIGHT, BUTTON_R2, AXIS_RTRIGGER, AXIS_THROTTLE fastForward() Avançar
DPAD_LEFT, BUTTON_L2, AXIS_LTRIGGER, AXIS_BRAKE rewind() Voltar
N/A stop() Parar

Fornecer o comportamento adequado do botão "Voltar"

O botão "Voltar" nunca pode funcionar como um botão de alternância. Por exemplo, não o use para abrir e fechar um menu. Use-o apenas para navegar para trás, no estilo de navegação estrutural, pelas telas anteriores em que o jogador esteve.

Como o botão "Voltar" só realiza navegação linear para trás, é possível usá-lo para sair de um menu no app aberto por um botão diferente e retornar ao app. Pressionar o botão "Voltar" consecutivamente precisa sempre levar à tela inicial do Android TV. Por exemplo: jogo > tela de pausa do jogo > tela principal do jogo > tela inicial do Android TV ou reprodução de programa de TV > tela principal do app de TV.

Tela inicial do Android TV.

Para mais informações sobre o design de navegação, consulte Como projetar a navegação de retorno e para cima. Para saber mais sobre a implementação, consulte Como fornecer uma navegação de retorno adequada.

Gerenciar controladores para jogos

Ao criar jogos para o Android TV, projete o esquema de controle para funcionar com controles remotos da TV padrão e controles de jogo dedicados.

Compatibilidade com controles D-pad

Planeje seu esquema de controle em torno de um botão direcional, já que esse conjunto de controles é o padrão para dispositivos Android TV. O jogador precisa ser capaz de usar um botão direcional para todos os aspectos do jogo, não apenas para controlar a jogabilidade principal, mas também para navegar em menus e anúncios. Por esse motivo, verifique se o jogo para Android TV não se refere a uma interface de toque com linguagem como "Toque aqui para continuar".

A forma como você molda a interação do jogador com o controle pode ser fundamental para proporcionar uma ótima experiência do usuário. Considere as práticas recomendadas a seguir:

  • Comunique os requisitos do controle com antecedência: use a descrição do Google Play para informar ao jogador as expectativas sobre os controles. Se um jogo for mais adequado para um gamepad com joystick do que para um com apenas um botão direcional, deixe isso claro. Um jogador que usa um controle inadequado para um jogo pode ter uma experiência ruim e dar uma classificação ruim ao jogo.
  • Use um mapeamento de botões consistente: um mapeamento de botões intuitivo é fundamental para uma boa experiência do usuário. Por exemplo, siga os costumes aceitos usando o botão A para aceitar e o botão B para cancelar. Você também pode oferecer flexibilidade permitindo que o usuário remapeie os botões. Para mais informações sobre o mapeamento de botões, consulte Processar ações do controle.
  • Detectar os recursos do controle e ajustar de acordo: consulte o controle sobre os recursos dele para otimizar a correspondência entre o controle e o jogo. Por exemplo, você pode querer que um jogador controle um objeto movendo o controle no ar, mas se o controle do jogador não tiver hardware de acelerômetro e giroscópio, o movimento não vai funcionar. Consulte o controlador e, se a detecção de movimento não for compatível, mude para um esquema de controle alternativo disponível. Para mais informações sobre como consultar recursos do controle, consulte Compatibilidade com controles em diversas versões do Android.

Usar os botões apropriados

Nem todos os controladores de jogos oferecem os botões "Iniciar", "Pesquisar" ou "Menu". Verifique se a interface não depende do uso desses botões.

Gerenciar vários controles

Quando várias pessoas estão jogando, cada uma com o próprio controle, é importante mapear cada par de jogador e controle. Para saber como implementar a identificação do número do controle, consulte getControllerNumber().

Tratar desconexões do controlador

Quando um controle for desconectado no meio do jogo, pause o jogo e mostre uma caixa de diálogo solicitando que o jogador reconecte o controle.

Além disso, ofereça dicas de solução de problemas na caixa de diálogo. Por exemplo, peça para o jogador "Verificar a conexão Bluetooth". Para mais informações sobre como implementar o suporte a dispositivos de entrada, consulte Processar ações do controle e a Visão geral do Bluetooth.

Mostrar instruções de controladores

Se o seu jogo fornecer instruções visuais de controle de jogo, use uma imagem de controle de jogo sem marca e inclua apenas botões compatíveis com o Android.

Para ver exemplos de imagens de um controle compatível com Android, faça o download do modelo de gamepad do Android TV (ZIP). Ele inclui um controle branco em um fundo preto e um controle preto em um fundo branco, mostrados na figura 1, como um arquivo PNG e um arquivo do Adobe® Illustrator®.

**Figura 1.** Exemplo de instruções do controle usando o modelo de gamepad do Android TV.