Ekran główny Androida TV (lub po prostu ekran główny) ma interfejs, który umożliwia wyświetla polecane treści w formie tabeli kanałów i programów. Każdy wiersz to kanał. Kanał zawiera karty wszystkich programów dostępnych na tym kanale:
Ten dokument pokazuje, jak dodawać kanały i programy do ekranu głównego, aktualizować treści, wykonywać działania użytkowników i zapewniać im najlepsze wrażenia. (Jeśli chcesz dokładniej poznać interfejs API, wypróbuj ćwiczenia z programowania na ekranie głównym i obejrzyj sesję I/O na Androidzie TV).
Uwaga: kanały rekomendacji są dostępne tylko w tych krajach: Android 8.0 (poziom interfejsu API 26) i nowsze. Należy ich używać do przesyłania zalecenia dotyczące aplikacji działających w Androidzie 8.0 (poziom interfejsu API 26) i nowszych. Do zalecenia dotyczące aplikacji działających na starszych wersjach Androida, musi użyć funkcji wiersz rekomendacji .
Interfejs ekranu głównego
Aplikacje mogą tworzyć nowe kanały, dodawać, usuwać i aktualizować programy na kanale oraz kontrolować ich kolejność. Na przykład aplikacja może utworzyć kanał o nazwie „Co nowego”. i wyświetlać karty nowych programów.
Aplikacje nie mogą kontrolować kolejności, w jakiej kanały pojawiają się na ekranie głównym. Gdy Twoja aplikacja utworzy nowy kanał, na ekranie głównym będzie się on pojawiać u dołu listy kanałów. Użytkownik może zmieniać kolejność, ukrywać i pokazywać kanały.
Kanał Warte obejrzenia
Kanał Warte obejrzenia to drugi rząd na ekranie głównym, w wierszu aplikacji. System tworzy i utrzymuje ten kanał. Aplikacja może dodawać na kanale Warte obejrzenia. Więcej informacji znajdziesz w artykule Dodawanie programów do kanał „Warte obejrzenia”.
Kanały aplikacji
Kanały tworzone przez aplikację podlegają temu cyklowi życia:
- Użytkownik znajduje kanał w Twojej aplikacji i prosi o dodanie go do ekranu głównego.
- Aplikacja utworzy kanał i doda go do
TvProvider
(w tym momencie kanał nie jest widoczny). - Aplikacja prosi system o wyświetlenie kanału.
- System prosi użytkownika o zatwierdzenie nowego kanału.
- Nowy kanał pojawi się w ostatnim wierszu ekranu głównego.
Kanał domyślny
Aplikacja może oferować dowolną liczbę kanałów, które użytkownik może dodać do ekranu głównego. Zwykle użytkownik musi wybierz i zatwierdź każdy kanał, zanim pojawi się na ekranie głównym. Każda aplikacja ma możliwość utworzenia jednego domyślnego kanału. Kanał domyślny jest wyjątkowy, ponieważ automatycznie pojawia się na ekranie głównym. użytkownik nie musi wyraźnie o to prosić.
Wymagania wstępne
Ekran główny Androida TV używa interfejsów API Androida TvProvider
do zarządzania kanałami i programami tworzonymi przez Twoją aplikację.
Aby uzyskać dostęp do danych dostawcy, dodaj do pliku manifestu aplikacji te uprawnienia:
<uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA" />
Biblioteka pomocy TvProvider
ułatwia korzystanie z usług dostawcy. Dodaj ją do zależności w pliku build.gradle
:
Odlotowe
implementation 'androidx.tvprovider:tvprovider:1.0.0'
Kotlin
implementation("androidx.tvprovider:tvprovider:1.0.0")
Aby móc pracować z kanałami i programami, uwzględnij w programie te zaimportowane biblioteki pomocnicze:
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;
Kanały
Pierwszy kanał utworzony przez aplikację staje się kanałem domyślnym. Kanał domyślny pojawi się automatycznie na ekranie głównym. Wszystkie inne utworzone przez Ciebie kanały muszą zostać wybrane i zaakceptowane przez użytkownika, zanim pojawią się na ekranie głównym.
Tworzenie kanału
Aplikacja powinna prosić system o wyświetlenie nowo dodanych kanałów tylko wtedy, gdy działa na pierwszym planie. Dzięki temu aplikacja nie będzie wyświetlać okna z prośbą o zatwierdzenie dodania kanału, gdy użytkownik korzysta z innej aplikacji. Jeśli spróbujesz dodać kanał, gdy działasz w tle, metoda onActivityResult()
aktywności zwróci kod stanu RESULT_CANCELED
.
Aby utworzyć kanał, wykonaj te czynności:
Utwórz kreator kanałów i ustaw jego atrybuty. Pamiętaj, że parametr Typ kanału musi być ustawiony na
TYPE_PREVIEW
. Dodaj więcej atrybuty.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);Wstaw kanał do dostawcy:
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());
-
Musisz zapisać identyfikator kanału, aby móc dodać do niego programy później. Wyodrębnij identyfikator kanału ze zwróconego identyfikatora URI:
Kotlin
var channelId = ContentUris.parseId(channelUri)
Java
long channelId = ContentUris.parseId(channelUri);
Musisz dodać logo kanału. Użyj pola
Uri
lubBitmap
. Logo ikona powinna mieć wymiary 80 dp x 80 dp i być nieprzezroczysta. Jest wyświetlany pod okrągła maska: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);
Utwórz kanał domyślny (opcjonalnie): gdy aplikacja utworzy po raz pierwszy Twój kanał może być kanału domyślnego, dzięki czemu będzie widoczny na stronie głównej. ekran bez żadnego działania ze strony użytkownika. Inne utworzone przez Ciebie kanały nie są widoczne, dopóki użytkownik nie wyrazi na to zgody wybierze je.
Kotlin
TvContractCompat.requestChannelBrowsable(context, channelId)
Java
TvContractCompat.requestChannelBrowsable(context, channelId);
- Spraw, aby kanał domyślny był widoczny przed otwarciem aplikacji. Dostępne opcje
aby to działało, dodaj element
BroadcastReceiver
, który nasłuchujeandroid.media.tv.action.INITIALIZE_PROGRAMS
, czyli działanie ekranu głównego wysyła po zainstalowaniu aplikacji: Jeśli instalujesz aplikację z innego urządzenia w trakcie jej programowania, możesz przetestować ten krok, za pomocą narzędzia adb, który aktywuje intencję, your.package.name/.YourReceiverName to adres Twojej aplikacji<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
W rzadkich przypadkach aplikacja może odbierać transmisję w tym samym czasie co użytkownik uruchomi aplikację. Upewnij się, że za pomocą kodu nie można dodać kanału domyślnego więcej niż raz.
Aktualizowanie kanału
Aktualizowanie kanałów jest bardzo podobne do ich tworzenia.
Użyj innego elementu Channel.Builder
, aby ustawić atrybuty, które musisz zmienić.
Użyj aplikacji ContentResolver
, aby zaktualizować kanał. Użyj identyfikatora kanału zapisanego podczas jego dodawania:
Kotlin
context.contentResolver.update( TvContractCompat.buildChannelUri(channelId), builder.build().toContentValues(), null, null )
Java
context.getContentResolver().update(TvContractCompat.buildChannelUri(channelId), builder.build().toContentValues(), null, null);
Aby zaktualizować logo kanału, użyj storeChannelLogo()
.
Usuwanie kanału
Kotlin
context.contentResolver.delete(TvContractCompat.buildChannelUri(channelId), null, null)
Java
context.getContentResolver().delete(TvContractCompat.buildChannelUri(channelId), null, null);
Programy
Dodawanie programów do kanału aplikacji
Utwórz obiekt PreviewProgram.Builder
i ustaw jego atrybuty:
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);
Dodaj więcej atrybutów w zależności od typu programu. (Aby wyświetlić atrybuty w przypadku każdego typu programu znajdziesz w tabelach poniżej).
Wstaw program w systemie dostawcy:
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());
Pobierz identyfikator programu do późniejszego wykorzystania:
Kotlin
val programId = ContentUris.parseId(programUri)
Java
long programId = ContentUris.parseId(programUri);
Dodawanie programów do kanału Warte obejrzenia
Aby wstawić programy na kanale Warte obejrzenia, przeczytaj artykuł Dodawanie programów do sekcji Obejrzyj Następny kanał.
Aktualizowanie programu
Informacje o programie możesz zmienić. Możesz na przykład zaktualizować cenę wypożyczania filmu lub zaktualizować pasek postępu pokazujący, jaką część programu obejrzał użytkownik.
Użyj PreviewProgram.Builder
, aby ustawić atrybuty, które chcesz zmienić.
a następnie wywołaj getContentResolver().update
, aby zaktualizować program. Podaj identyfikator programu zapisany podczas dodawania programu:
Kotlin
context.contentResolver.update( TvContractCompat.buildPreviewProgramUri(programId), builder.build().toContentValues(), null, null )
Java
context.getContentResolver().update(TvContractCompat.buildPreviewProgramUri(programId), builder.build().toContentValues(), null, null);
Usuwanie programu
Kotlin
context.contentResolver .delete(TvContractCompat.buildPreviewProgramUri(programId), null, null)
Java
context.getContentResolver().delete(TvContractCompat.buildPreviewProgramUri(programId), null, null);
Obsługa działań użytkowników
Twoja aplikacja może pomóc użytkownikom w odkrywaniu treści, udostępniając interfejs do wyświetlania i dodawania kanałów. Aplikacja powinna też obsługiwać interakcje z kanałami, gdy pojawią się one na ekranie głównym.
Odkrywanie i dodawanie kanałów
Aplikacja może zawierać element interfejsu, który umożliwia użytkownikowi wybranie i dodanie kanałów (np. przycisk umożliwiający dodanie kanału).
Gdy użytkownik poprosi o dostęp do konkretnego kanału, uruchom ten kod, aby uzyskać zgodę użytkownika na dodanie go do interfejsu użytkownika ekranu głównego:
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 }
System wyświetli okno z prośbą o zatwierdzenie kanału.
Przetwórz wynik żądania w metodzie onActivityResult
Twojej aktywności (Activity.RESULT_CANCELED
lub Activity.RESULT_OK
).
Zdarzenia na ekranie głównym Androida TV
Gdy użytkownik wchodzi w interakcję z programami lub kanałami opublikowanymi przez aplikację, ekran główny wysyła do niej intencje:
- Gdy użytkownik wybierze logo kanału, ekran główny wysyła do aplikacji
Uri
zapisane w atrybucie APP_LINK_INTENT_URI kanału. Aplikacja powinna po prostu uruchomić główny interfejs lub widok związany z wybranym kanałem. - Gdy użytkownik wybierze program, ekran główny wysyła do aplikacji
Uri
zapisane w atrybucie INTENT_URI programu. Aplikacja powinna odtworzyć wybrane treści. - Użytkownik może wskazać, że nie jest już zainteresowany programem i chce usunąć go z interfejsu na ekranie głównym. System usuwa program z interfejsu i wysyła do aplikacji będącej jego właścicielem intencję (android.media.tv.ACTION_PREVIEW_PROGRAM_BROWSABLE_DISABLED lub android.media.tv.ACTION_WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED) z identyfikatorem programu. Aplikacja powinna usunąć program od dostawcy i NIE należy go instalować ponownie.
Pamiętaj, aby utworzyć filtry intencji dla wszystkich elementów typu Uris
wysyłanych przez ekran główny w przypadku interakcji użytkownika. np.:
<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>
Sprawdzone metody
- Wiele aplikacji telewizyjnych wymaga zalogowania się. W tym przypadku
BroadcastReceiver
który słucha przezandroid.media.tv.action.INITIALIZE_PROGRAMS
, powinien zaproponować treści na kanale dla nieuwierzytelnionych użytkowników.Na przykład aplikacja może początkowo pokazuje najlepsze lub aktualnie popularne treści. Gdy użytkownik się zaloguje, mogą wyświetlać spersonalizowane treści. To świetna okazja, by zwiększyć sprzedaż aplikacji użytkowników przed zalogowaniem się. - Gdy aplikacja nie działa na pierwszym planie i musisz zaktualizować kanał lub
programu, użyj
JobScheduler
, aby zaplanować pracę (zobacz: Harmonogram zadań i JobService). - System może anulować uprawnienia dostawcy aplikacji, jeśli aplikacja będzie działać nieprawidłowo (na przykład przez ciągłe spamowanie dostawcy danymi). Upewnij się, że opakuj kod uzyskujący dostęp do dostawcy za pomocą klauzul try-catch do obsługi wyjątki od zabezpieczeń.
Zanim zaktualizujesz programy i kanały, poproś dostawcę o dane, które trzeba zaktualizować i uzgodnić. Nie trzeba na przykład aktualizować program, który użytkownik chce usunąć z interfejsu. Użyj zadania w tle, które wstawia/aktualizuje Twoje dane u dostawcy po wysłaniu zapytania o istniejące dane z danymi, a następnie o zatwierdzenie kanału. Możesz uruchomić to zadanie, gdy Aplikacja uruchamia się i wymaga zaktualizowania danych.
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 } } }
Używaj unikalnych identyfikatorów URI do wszystkich obrazów (logo, ikon, obrazów treści). Pamiętaj, aby podczas aktualizowania obrazu użyć innego identyfikatora URI. Wszystkie obrazy są przechowywane w pamięci podręcznej. Jeśli nie zmienisz identyfikatora URI po zmianie obrazu, stary obraz nadal będzie wyświetlany.
Pamiętaj, że klauzule WHERE są niedozwolone, a wywołania dostawców z klauzulami WHERE będą zgłaszać wyjątek od zabezpieczeń.
Atrybuty
W tej sekcji opisano oddzielnie atrybuty kanału i programu.
Atrybuty kanału
Musisz określić dla każdego kanału te atrybuty:
Atrybut | Uwagi |
---|---|
TYP | ustaw jako TYPE_PREVIEW . |
DISPLAY_NAME | musi zawierać nazwę kanału. |
APP_LINK_INTENT_URI | Gdy użytkownik wybierze logo kanału, system wysyła zamiar rozpoczęcia działania, które przedstawia treści pasujące do kanału. Ustaw ten atrybut na identyfikator URI używany w filtrze intencji dla tej aktywności. |
Dodatkowo kanał ma 6 pól zarezerwowanych na potrzeby wewnętrznego użycia aplikacji. W tych polach możesz zapisywać klucze lub inne wartości, które pomagają aplikacji mapować kanał na wewnętrzną strukturę danych:
- INTERNAL_PROVIDER_ID (Identyfikator_WEWNĘTRZNEGO DOSTAWCY)
- DANE_WEWNĘTRZNE
- DOSTAWCA_WEWNĘTRZNY_FLAG1
- DOSTAWCA_WEWNĘTRZNY_FLAG2
- DOSTAWCA_WEWNĘTRZNY_FLAG3
- DOSTAWCA_WEWNĘTRZNY_FLAG4
Atrybuty programu
Szczegółowe informacje o atrybutach poszczególnych typów programów znajdziesz na stronach:
- Atrybuty programu wideo
- Atrybuty programu audio
- Atrybuty programu gier
- Atrybuty programu Warte obejrzenia
Kod demonstracyjny
Aby dowiedzieć się więcej o tworzeniu aplikacji, które wchodzą w interakcję z ekranem głównym oraz dodają kanały i programy do ekranu głównego Androida TV, zapoznaj się z ćwiczeniami z programowania dotyczącymi ekranu głównego.