Ekran główny Androida TV (lub po prostu ekran główny) to interfejs, który wyświetla rekomendowane treści w postaci tabeli kanałów i programów. Każdy wiersz odpowiada kanałowi. Na kanale znajdują się 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 zapewnić użytkownikom najlepsze wrażenia. (Jeśli chcesz dowiedzieć się więcej o interfejsie API, wykonaj ćwiczenia z programowania dotyczące ekranu głównego i obejrzyj sesję I/O 2017 na temat Androida TV).
Uwaga: kanały rekomendacji są dostępne tylko na Androidzie 8.0 (poziom interfejsu API 26) i nowszych. Musisz ich używać do podawania rekomendacji aplikacji działających na Androidzie 8.0 (poziom interfejsu API 26) i nowszych. Aby udostępniać rekomendacje dotyczące aplikacji działających na wcześniejszych wersjach Androida, Twoja aplikacja musi używać wiersza rekomendacji.
Interfejs ekranu głównego
Aplikacje mogą tworzyć nowe kanały, dodawać, usuwać i aktualizować programy na kanale oraz kontrolować kolejność programów na kanale. Na przykład aplikacja może utworzyć kanał o nazwie „Co nowego” i wyświetlać karty dotyczące nowo dostępnych programów.
Aplikacje nie mogą kontrolować kolejności, w jakiej kanały pojawiają się na ekranie głównym. Gdy aplikacja utworzy nowy kanał, na ekranie głównym zostanie on dodany na dole listy kanałów. Użytkownik może zmieniać kolejność, ukrywać i pokazywać kanały.
Kanał Warte obejrzenia
Kanał „Warte obejrzenia” to drugi wiersz na ekranie głównym, po wierszu aplikacji. System utworzy i będzie utrzymywać ten kanał. Twoja aplikacja może dodawać programy do kanału Warte obejrzenia. Więcej informacji znajdziesz w artykule Dodawanie programów na kanale Warte obejrzenia.
Kanały aplikacji
Kanały tworzone przez aplikację są zgodne z tym cyklem życia:
- Użytkownik odkrywa kanał w Twojej aplikacji i prosi o dodanie go do ekranu głównego.
- Aplikacja tworzy kanał i dodaje go do sekcji
TvProvider
(w tym momencie kanał jest niewidoczny). - Aplikacja poprosi 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. Zanim kanał pojawi się na ekranie głównym, użytkownik musi najpierw wybrać i zatwierdzić. Każda aplikacja ma opcję utworzenia jednego domyślnego kanału. Kanał domyślny jest specjalny, ponieważ automatycznie pojawia się na ekranie głównym. Użytkownik nie musi o to prosić.
Wymagania wstępne
Ekran główny Androida TV używa interfejsów API TvProvider
Androida do zarządzania kanałami i programami, które tworzy Twoja aplikacja.
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 go do zależności w pliku build.gradle
:
Odlotowy
implementation 'androidx.tvprovider:tvprovider:1.0.0'
Kotlin
implementation("androidx.tvprovider:tvprovider:1.0.0")
Aby korzystać z kanałów i programów, musisz uwzględnić w programie te operacje importowania bibliotek:
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 Twoją 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ć o wyświetlanie nowo dodanych kanałów tylko wtedy, gdy działa na pierwszym planie. Dzięki temu w aplikacji nie będzie wyświetlane okno z prośbą o zatwierdzenie dodania kanału, gdy użytkownik korzysta z innej aplikacji. Jeśli spróbujesz dodać kanał, gdy działa on 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 typem kanału musi być
TYPE_PREVIEW
. W razie potrzeby dodaj więcej atrybutów.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 później dodawać do niego programy. 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 do kanału. Użyj
Uri
lubBitmap
. Ikona logo powinna mieć wymiary 80 x 80 dp i być nieprzezroczysta. Wyświetla się pod okrągłą maską: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 Twoja aplikacja utworzy swój pierwszy kanał, możesz ustawić go jako kanał domyślny, aby od razu pojawiał się na ekranie głównym bez żadnych działań ze strony użytkownika. Inne utworzone przez Ciebie kanały nie będą widoczne, dopóki użytkownik ich nie wybierzesz.
Kotlin
TvContractCompat.requestChannelBrowsable(context, channelId)
Java
TvContractCompat.requestChannelBrowsable(context, channelId);
- Ustaw kanał domyślny przed otwarciem aplikacji. Możesz to osiągnąć, dodając obiekt
BroadcastReceiver
, który nasłuchuje działaniaandroid.media.tv.action.INITIALIZE_PROGRAMS
wysyłanego przez ekran główny po zainstalowaniu 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>
Podczas instalowania aplikacji z nieoficjalnych źródeł możesz przetestować ten krok, wywołując intencję za pomocą adb, gdzie your.package.name/.YourReceiverName toBroadcastReceiver
aplikacji:adb shell am broadcast -a android.media.tv.action.INITIALIZE_PROGRAMS -n \ your.package.name/.YourReceiverName
W rzadkich przypadkach aplikacja może odebrać komunikat w tym samym czasie, gdy użytkownik ją uruchomi. Nie próbuj dodać kanału domyślnego więcej niż raz.
Aktualizowanie kanału
Aktualizowanie kanałów przebiega podobnie do ich tworzenia.
Aby określić atrybuty, które muszą zostać zmienione, użyj innego elementu Channel.Builder
.
Użyj przycisku ContentResolver
, aby zaktualizować kanał. Użyj identyfikatora kanału zapisanego podczas dodawania kanału:
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 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. (listę atrybutów dostępnych w przypadku poszczególnych typów programu znajdziesz w tabelach poniżej).
Wstaw program do 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 na kanale Warte obejrzenia
Aby wstawiać programy na kanale Warte obejrzenia, zapoznaj się z sekcją Dodawanie programów na kanale Warte obejrzenia.
Aktualizowanie programu
Informacje o programie można zmieniać. Możesz na przykład zaktualizować cenę wypożyczenia filmu lub pasek postępu pokazujący, jaka część programu obejrzał użytkownik.
Użyj PreviewProgram.Builder
, aby ustawić atrybuty, które trzeba zmienić, a następnie wywołaj getContentResolver().update
, aby zaktualizować program. Podaj identyfikator programu zapisany podczas jego dodawania:
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żytkownika
Aplikacja może ułatwić użytkownikom odkrywanie treści, udostępniając interfejs do wyświetlania i dodawania kanałów. Aplikacja powinna też obsługiwać interakcje z kanałami po ich pojawieniu się na ekranie głównym.
Odkrywanie i dodawanie kanałów
Aplikacja może zawierać element interfejsu, który pozwala użytkownikowi wybrać i dodać kanały (np. przycisk z prośbą o dodanie kanału).
Gdy użytkownik poprosi o dostęp do konkretnego kanału, wykonaj ten kod, aby uzyskać uprawnienia do dodania go do interfejsu 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
swojej 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 parametr
Uri
zapisany w atrybucie APP_LINK_INTENT_uri kanału. Aplikacja powinna uruchomić swój główny interfejs lub widok powiązany z wybranym kanałem. - Gdy użytkownik wybierze program, ekran główny wysyła do aplikacji
Uri
zapisany w atrybucie INTENT_uri programu. Aplikacja powinna odtworzyć wybraną treść. - Użytkownik może zaznaczyć, że nie jest już zainteresowany programem i poprosić o usunięcie 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 usuwać program u dostawcy i NIE powinna dodawać go ponownie.
Utwórz filtry intencji dla wszystkich elementów Uris
, które ekran główny wysyła w związku z interakcjami użytkownika, na przykład:
<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 na telewizory wymaga zalogowania się. W takim przypadku
BroadcastReceiver
, który nasłuchuje poleceniaandroid.media.tv.action.INITIALIZE_PROGRAMS
, powinien sugerować treści na kanale nieuwierzytelnionym użytkownikom.Aplikacja może na przykład początkowo wyświetlać najlepsze treści lub aktualnie popularne treści. Po zalogowaniu się użytkownika mogą wyświetlać spersonalizowane treści. Dzięki temu aplikacje mogą zwiększyć sprzedaż użytkowników, zanim się zalogują. - Jeśli aplikacja nie działa na pierwszym planie i chcesz zaktualizować kanał lub program, użyj
JobScheduler
do zaplanowania pracy (zobacz: JobScheduler i JobService). - System może cofnąć uprawnienia dostawcy aplikacji, jeśli aplikacja działa niepoprawnie (np. stale spamuje dostawcę danymi). Pamiętaj, aby opakować kod, który uzyskuje dostęp do dostawcy, klauzulami try-catch, które obsługują wyjątki dotyczące zabezpieczeń.
Przed aktualizacją programów i kanałów poproś dostawcę o dane, które chcesz zaktualizować i uzgodnić. Nie ma na przykład potrzeby aktualizowania programu, który użytkownik chce usunąć z interfejsu. użyć zadania w tle, które wstawia lub aktualizuje Twoje dane u dostawcy po wysłaniu zapytania o istniejące dane, a następnie poproszenia o zatwierdzenie kanałów. Możesz je uruchamiać podczas uruchamiania aplikacji lub za każdym razem, gdy trzeba zaktualizować dane.
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 przy aktualizacji obrazu użyć innego identyfikatora URI. Wszystkie obrazy są zapisywane w pamięci podręcznej. Jeśli podczas edytowania obrazu nie zmienisz identyfikatora URI, stary obraz będzie nadal wyświetlany.
Pamiętaj, że klauzule WHERE są niedozwolone, a wywołania dostawców z klauzulami WHERE będą zgłaszać wyjątek bezpieczeństwa.
Atrybuty
W tej sekcji opisujemy atrybuty kanału i programu oddzielnie.
Atrybuty kanału
Musisz określić te atrybuty dla każdego kanału:
Atrybut | Uwagi |
---|---|
TYP | ustaw na TYPE_PREVIEW . |
DISPLAY_NAME | ustawiony na nazwę kanału. |
APP_LINK_INTENT_uri | Gdy użytkownik wybierze logo kanału, system wyśle prośbę o rozpoczęcie działania, które przedstawia treści związane z kanałem. Ustaw ten atrybut na identyfikator URI używany w filtrze intencji dla tej aktywności. |
Dodatkowo kanał ma też 6 pól zarezerwowanych do użytku wewnętrznego w aplikacjach. Te pola mogą służyć do przechowywania kluczy i innych wartości, które ułatwiają mapowanie kanału na wewnętrzną strukturę danych:
- WEWNĘTRZNY_IDENTYFIKATOR_DOSTAWCY
- DANE_DOSTAWCY WEWNĘTRZNE
- WEWNĘTRZNY_DOSTAWCA_FLAG1
- INTERNAL_PROVIDER_FLAG2
- WEWNĘTRZNY_DOSTAWCA_FLAG3
- WEWNĘTRZNY_DOSTAWCA_FLAG4
Atrybuty programu
Sprawdź atrybuty poszczególnych typów programów na poszczególnych stronach:
- Atrybuty programu wideo
- Atrybuty programu audio
- Atrybuty programu gier
- Atrybuty programu Warte obejrzenia
Kod demonstracyjny
Więcej informacji o tworzeniu aplikacji, które wchodzą w interakcję z ekranem głównym oraz o dodawaniu kanałów i programów do ekranu głównego Androida TV, znajdziesz w ćwiczeniach z programowania na ekranie głównym.