A tela inicial do Android TV, ou simplesmente tela inicial, fornece uma interface que exibe o conteúdo recomendado como uma tabela de canais e programas. Cada linha é um canal. Um canal contém cards para todos os programas disponíveis nele:
Este documento demonstra como adicionar canais e programas à tela inicial, atualizar o conteúdo, lidar com ações do usuário e fornecer a melhor experiência para seus usuários. (Se quiser se aprofundar na API, experimente o codelab da tela inicial e assista à sessão do Android TV do I/O 2017 (em inglês).
Observação:os canais de recomendações estão disponíveis apenas em Android 8.0 (nível 26 da API) e versões mais recentes. Você deve usá-los para fornecer recomendações para apps em execução no Android 8.0 (nível 26 da API) e versões mais recentes. Para fornecer recomendações para apps executados em versões anteriores do Android, seu app é necessário usar o linha de recomendações como alternativa.
A IU da tela inicial
Os apps podem criar novos canais, adicionar, remover e atualizar os programas em um canal e controlar a ordem dos programas em um canal. Por exemplo, um app pode criar um canal chamado "Novidades" e mostrar cards de programas recém-disponibilizados.
Os apps não podem controlar a ordem em que os canais aparecem na tela inicial. Quando seu app cria um novo canal, a tela inicial o adiciona à parte inferior da lista de canais. O usuário pode reordenar, ocultar e mostrar canais.
O canal "Assistir a seguir"
O canal "Assistir a seguir" é a segunda linha que aparece na tela inicial, depois de linha "Apps". O sistema cria e mantém esse canal. Seu app pode adicionar programas para o canal "Assistir a seguir". Para mais informações, consulte Adicionar programas ao canal "Assistir a seguir".
Canais do app
Todos os canais criados pelo seu app seguem este ciclo de vida:
- O usuário descobre um canal no seu app e solicita que ele seja adicionado à tela inicial.
- O app cria o canal e o adiciona a
TvProvider
(nesse ponto, o canal não está visível). - O app solicita que o sistema exiba o canal.
- O sistema pede que o usuário aprove o novo canal.
- O novo canal aparece na última linha da tela inicial.
O canal padrão
Seu app pode oferecer qualquer número de canais para o usuário adicionar à tela inicial. O usuário geralmente precisa selecione e aprove cada canal antes que ele apareça na tela inicial. Cada app tem a opção de criar um canal padrão. O canal padrão é especial, porque aparece automaticamente na tela inicial. o usuário não precisa solicitá-la explicitamente.
Pré-requisitos
A tela inicial da Android TV usa as APIs TvProvider
do Android para gerenciar os canais e programas criados pelo seu app.
Para acessar os dados do provedor, adicione a seguinte permissão ao manifesto do seu app:
<uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA" />
A Biblioteca de Suporte TvProvider
facilita o uso do provedor. Adicione-a às dependências no seu arquivo build.gradle
:
Groovy
implementation 'androidx.tvprovider:tvprovider:1.0.0'
Kotlin
implementation("androidx.tvprovider:tvprovider:1.0.0")
Para trabalhar com canais e programas, não se esqueça de incluir estas importações da Biblioteca de Suporte no seu programa:
Kotlin
import android.support.media.tv.Channel import android.support.media.tv.TvContractCompat import android.support.media.tv.ChannelLogoUtils import android.support.media.tv.PreviewProgram import android.support.media.tv.WatchNextProgram
Java
import android.support.media.tv.Channel; import android.support.media.tv.TvContractCompat; import android.support.media.tv.ChannelLogoUtils; import android.support.media.tv.PreviewProgram; import android.support.media.tv.WatchNextProgram;
Canais
O primeiro canal criado pelo app se torna o canal padrão. O canal padrão é exibido automaticamente na tela inicial. Todos os outros canais que você criar precisam ser selecionados e aceitos pelo usuário antes de serem exibidos na tela inicial.
Como criar um canal
Seu app pedirá ao sistema para mostrar os canais adicionados recentemente apenas quando ele estiver sendo executado em primeiro plano. Isso impede que o app exiba uma caixa de diálogo solicitando aprovação para adicionar seu canal enquanto o usuário estiver usando um app diferente. Se você tentar adicionar um canal durante a execução em segundo plano, o método onActivityResult()
da atividade retornará o código de status RESULT_CANCELED
.
Para criar um canal, siga estas etapas:
Crie um gerador de canal e defina os atributos dele. Observe que o o tipo de canal precisa ser
TYPE_PREVIEW
. Adicionar mais attributes conforme necessário.Kotlin
val builder = Channel.Builder() // Every channel you create must have the type
TYPE_PREVIEW
builder.setType(TvContractCompat.Channels.TYPE_PREVIEW) .setDisplayName("Channel Name") .setAppLinkIntentUri(uri)Java
Channel.Builder builder = new Channel.Builder(); // Every channel you create must have the type
TYPE_PREVIEW
builder.setType(TvContractCompat.Channels.TYPE_PREVIEW) .setDisplayName("Channel Name") .setAppLinkIntentUri(uri);Insira o canal no provedor:
Kotlin
var channelUri = context.contentResolver.insert( TvContractCompat.Channels.CONTENT_URI, builder.build().toContentValues())
Java
Uri channelUri = context.getContentResolver().insert( TvContractCompat.Channels.CONTENT_URI, builder.build().toContentValues());
-
É necessário salvar o ID do canal para adicionar programas a ele mais tarde. Extraia o ID do canal do URI retornado:
Kotlin
var channelId = ContentUris.parseId(channelUri)
Java
long channelId = ContentUris.parseId(channelUri);
Você precisa adicionar um logotipo para seu canal. Use um
Uri
ouBitmap
. O logotipo precisa ter 80 dp x 80 dp e ser opaco. Ele é exibido em um máscara circular:Kotlin
// Choose one or the other storeChannelLogo(context: Context, channelId: Long, logoUri: Uri) // also works if logoUri is a URL storeChannelLogo(context: Context, channelId: Long, logo: Bitmap)
Java
// Choose one or the other storeChannelLogo(Context context, long channelId, Uri logoUri); // also works if logoUri is a URL storeChannelLogo(Context context, long channelId, Bitmap logo);
Criar o canal padrão (opcional): quando seu app criar o primeiro canal. você pode torná-lo o canal padrão para que ele apareça na página inicial tela imediatamente, sem qualquer ação do usuário. Quaisquer outros canais que você criar não ficam visíveis até que o usuário seleciona essas pessoas.
Kotlin
TvContractCompat.requestChannelBrowsable(context, channelId)
Java
TvContractCompat.requestChannelBrowsable(context, channelId);
- Faça com que seu canal padrão apareça antes que o app seja aberto. Você pode
esse comportamento acontece adicionando um
BroadcastReceiver
que detecta oandroid.media.tv.action.INITIALIZE_PROGRAMS
, que a tela inicial envia após a instalação do app: Ao transferir o aplicativo por sideload durante o desenvolvimento, é possível testar essa etapa acionando a intent pelo adb, em que your.package.name/.YourReceiverName é do seu app<receiver android:name=".RunOnInstallReceiver" android:exported="true"> <intent-filter> <action android:name="android.media.tv.action.INITIALIZE_PROGRAMS" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </receiver>
BroadcastReceiver
:adb shell am broadcast -a android.media.tv.action.INITIALIZE_PROGRAMS -n \ your.package.name/.YourReceiverName
Em casos raros, o app pode receber a transmissão ao mesmo tempo que o usuário inicia seu app. Verifique se o código não tenta adicionar o canal padrão mais de uma vez.
Como atualizar um canal
Atualizar canais é muito semelhante a criá-los.
Use outro Channel.Builder
para definir os atributos que precisam ser mudados.
Use ContentResolver
para atualizar o canal. Use o ID do canal que você salvou quando o canal foi adicionado originalmente:
Kotlin
context.contentResolver.update( TvContractCompat.buildChannelUri(channelId), builder.build().toContentValues(), null, null )
Java
context.getContentResolver().update(TvContractCompat.buildChannelUri(channelId), builder.build().toContentValues(), null, null);
Para atualizar o logotipo de um canal, use storeChannelLogo()
.
Como excluir um canal
Kotlin
context.contentResolver.delete(TvContractCompat.buildChannelUri(channelId), null, null)
Java
context.getContentResolver().delete(TvContractCompat.buildChannelUri(channelId), null, null);
Programas
Como adicionar programas a um canal do app
Crie um PreviewProgram.Builder
e defina os atributos:
Kotlin
val builder = PreviewProgram.Builder() builder.setChannelId(channelId) .setType(TvContractCompat.PreviewPrograms.TYPE_CLIP) .setTitle("Title") .setDescription("Program description") .setPosterArtUri(uri) .setIntentUri(uri) .setInternalProviderId(appProgramId)
Java
PreviewProgram.Builder builder = new PreviewProgram.Builder(); builder.setChannelId(channelId) .setType(TvContractCompat.PreviewPrograms.TYPE_CLIP) .setTitle("Title") .setDescription("Program description") .setPosterArtUri(uri) .setIntentUri(uri) .setInternalProviderId(appProgramId);
Adicione mais atributos dependendo do tipo de programa. Para conferir os atributos disponíveis para cada tipo de programa, consulte as tabelas abaixo.)
Insira o programa no provedor:
Kotlin
var programUri = context.contentResolver.insert(TvContractCompat.PreviewPrograms.CONTENT_URI, builder.build().toContentValues())
Java
Uri programUri = context.getContentResolver().insert(TvContractCompat.PreviewPrograms.CONTENT_URI, builder.build().toContentValues());
Recupere o ID do programa para referência futura:
Kotlin
val programId = ContentUris.parseId(programUri)
Java
long programId = ContentUris.parseId(programUri);
Como adicionar programas ao canal "Assistir a seguir"
Para inserir programas no canal "Assistir a seguir", consulte Adicionar programas ao canal "Assistir a seguir" Próximo canal.
Como atualizar um programa
Você pode mudar as informações de um programa. Por exemplo, convém atualizar o preço do aluguel de um filme ou atualizar uma barra de progresso que mostra quanto de um programa o usuário assistiu.
Use um PreviewProgram.Builder
para definir os atributos que você precisa mudar.
Em seguida, chame getContentResolver().update
para atualizar o programa. Especifique o ID do programa que você salvou quando o programa foi adicionado originalmente:
Kotlin
context.contentResolver.update( TvContractCompat.buildPreviewProgramUri(programId), builder.build().toContentValues(), null, null )
Java
context.getContentResolver().update(TvContractCompat.buildPreviewProgramUri(programId), builder.build().toContentValues(), null, null);
Como excluir um programa
Kotlin
context.contentResolver .delete(TvContractCompat.buildPreviewProgramUri(programId), null, null)
Java
context.getContentResolver().delete(TvContractCompat.buildPreviewProgramUri(programId), null, null);
Como gerenciar ações do usuário
Seu app pode ajudar os usuários a descobrir o conteúdo fornecendo uma IU para exibir e adicionar canais. Ele também precisa lidar com interações com seus canais depois que eles aparecem na tela inicial.
Como descobrir e adicionar canais
Seu app pode fornecer um elemento de IU que permite ao usuário selecionar e adicionar canais (por exemplo, um botão que pede para adicionar o canal).
Depois que o usuário solicitar um canal específico, execute este código para receber a permissão do usuário para adicioná-lo à IU da tela inicial:
Kotlin
val intent = Intent(TvContractCompat.ACTION_REQUEST_CHANNEL_BROWSABLE) intent.putExtra(TvContractCompat.EXTRA_CHANNEL_ID, channelId) try { activity.startActivityForResult(intent, 0) } catch (e: ActivityNotFoundException) { // handle error }
Java
Intent intent = new Intent(TvContractCompat.ACTION_REQUEST_CHANNEL_BROWSABLE); intent.putExtra(TvContractCompat.EXTRA_CHANNEL_ID, channelId); try { activity.startActivityForResult(intent, 0); } catch (ActivityNotFoundException e) { // handle error }
O sistema exibe uma caixa de diálogo solicitando que o usuário aprove o canal.
Gerencie o resultado da solicitação no método onActivityResult
da sua atividade (Activity.RESULT_CANCELED
ou Activity.RESULT_OK
).
Eventos da tela inicial do Android TV
Quando o usuário interage com os programas/canais publicados pelo app, a tela inicial envia intents para o app:
- A tela inicial envia o
Uri
armazenado no atributo APP_LINK_INTENT_URI de um canal para o app quando o usuário seleciona o logotipo do canal. O app precisa abrir a IU principal ou uma visualização relacionada ao canal selecionado. - A tela inicial envia o
Uri
armazenado no atributo INTENT_URI de um programa para o app quando o usuário seleciona um programa. O app precisa reproduzir o conteúdo selecionado. - O usuário pode indicar que não está mais interessado em um programa e quer removê-lo da IU da tela inicial. O sistema removerá o programa da IU e enviará ao app proprietário do programa um intent (android.media.tv.ACTION_PREVIEW_PROGRAM_BROWSABLE_DISABLED ou android.media.tv.ACTION_WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED) com o ID do programa. O app precisa remover o programa do provedor e NÃO reinseri-lo.
Não esqueça de criar filtros de intent para todos os Uris
que a tela inicial envia para interações de usuário. Por exemplo:
<receiver
android:name=".WatchNextProgramRemoved"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.media.tv.ACTION_WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED" />
</intent-filter>
</receiver>
Práticas recomendadas
- Muitos apps de TV exigem que os usuários façam login. Nesse caso, o
BroadcastReceiver
que detectaandroid.media.tv.action.INITIALIZE_PROGRAMS
vai sugerir conteúdo do canal para usuários não autenticados.Por exemplo, seu app pode começar mostram o melhor conteúdo ou o conteúdo em alta no momento. Depois que o usuário faz login, ele podem mostrar conteúdo personalizado. Essa é uma ótima oportunidade para fazer o upsell dos apps usuários antes do login. - Quando seu app não está em primeiro plano e você precisa atualizar um canal ou um
programa, use o
JobScheduler
para programar o trabalho (consulte: JobScheduler e JobService). - O sistema pode revogar as permissões de provedor do seu aplicativo caso o aplicativo tenha um comportamento inadequado Por exemplo: enviar spam continuamente para o provedor com dados. Certifique-se de unem o código que acessa o provedor com cláusulas try-catch para lidar com exceções de segurança.
Antes de atualizar programas e canais, consulte o provedor para saber quais dados você precisam atualizar e reconciliar os dados. Por exemplo, não é preciso atualizar um programa que o usuário quer remover da interface. Use um job em segundo plano que insere/atualiza seus dados no provedor depois de consultar as e solicitar aprovação para seus canais. É possível executar esse job o aplicativo é iniciado e sempre que o aplicativo precisa atualizar seus dados.
Kotlin
context.contentResolver .query( TvContractCompat.buildChannelUri(channelId), null, null, null, null).use({ cursor-> if (cursor != null and cursor.moveToNext()) { val channel = Channel.fromCursor(cursor) if (channel.isBrowsable()) { //update channel's programs } } })
Java
try (Cursor cursor = context.getContentResolver() .query( TvContractCompat.buildChannelUri(channelId), null, null, null, null)) { if (cursor != null && cursor.moveToNext()) { Channel channel = Channel.fromCursor(cursor); if (channel.isBrowsable()) { //update channel's programs } } }
Use URIs exclusivos para todas as imagens (logotipos, ícones, imagens de conteúdo). Use um URI diferente ao atualizar uma imagem. Todas as imagens são armazenadas em cache. Se você não mudar o URI quando mudar a imagem, a imagem antiga continuará aparecendo.
Lembre-se de que cláusulas WHERE não são permitidas, e chamadas para os provedores com cláusulas WHERE gerarão uma exceção de segurança.
Atributos
Esta seção descreve os atributos do canal e do programa separadamente.
Atributos do canal
Você precisa especificar estes atributos para cada canal:
Atributo | Observações |
---|---|
TYPE | defina como TYPE_PREVIEW . |
DISPLAY_NAME | defina como o nome do canal. |
APP_LINK_INTENT_URI | Quando o usuário seleciona o logotipo do canal, o sistema envia um intent para iniciar uma atividade que apresenta conteúdo relevante para o canal. Defina esse atributo como o URI usado no filtro de intent dessa atividade. |
Além disso, um canal também tem seis campos reservados para uso interno do app. Esses campos podem ser usados para armazenar chaves ou outros valores que podem ajudar o app a mapear o canal para a estrutura de dados interna:
- INTERNAL_PROVIDER_ID
- INTERNAL_PROVIDER_DATA
- INTERNAL_PROVIDER_FLAG1
- INTERNAL_PROVIDER_FLAG2
- INTERNAL_PROVIDER_FLAG3
- INTERNAL_PROVIDER_FLAG4
Atributos do programa
Veja as páginas individuais para os atributos de cada tipo de programa:
- Atributos do programa de vídeo
- Atributos do programa de áudio
- Atributos do programa de jogo
- Atributos do programa do "Assistir a seguir"
Exemplo de código
Para saber mais sobre como criar apps que interagem com a tela inicial e adicionar canais e programas à tela inicial da Android TV, consulte o codelab da tela inicial.