Ekran główny Androida TV zawiera interfejs, w którym polecane treści są wyświetlane w tabeli kanałów i programów. Każdy wiersz to kanał. Kanał zawiera karty wszystkich programów dostępnych na tym kanale:
Z tego dokumentu dowiesz się, jak dodawać kanały i programy do ekranu głównego, aktualizować treści, obsługiwać działania użytkowników i zapewniać im jak najlepsze wrażenia. (Jeśli chcesz dowiedzieć się więcej o interfejsie API, wypróbuj codelab dotyczący ekranu głównego i obejrzyj sesję I/O 2017 dotyczącą Androida TV)
Interfejs ekranu głównego
Aplikacje mogą tworzyć nowe kanały, dodawać, usuwać i aktualizować programy na kanale oraz kontrolować kolejność programów na kanale. Aplikacja może na przykład utworzyć kanał o nazwie „Co nowego” i wyświetlać karty 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ł, ekran główny doda go na końcu listy kanałów. Użytkownik może zmieniać kolejność kanałów, ukrywać je i wyświetlać.
Kanał Warte obejrzenia
Kanał Warte obejrzenia to drugi wiersz, który pojawia się na ekranie głównym po wierszu aplikacji. Ten kanał jest tworzony i utrzymywany przez system. Twoja aplikacja może dodawać programy do kanału Warte obejrzenia. Więcej informacji znajdziesz w sekcji Dodawanie programów do kanału Warte obejrzenia.
Kanały aplikacji
Wszystkie kanały tworzone przez Twoją aplikację mają ten sam cykl życia:
- Użytkownik znajduje kanał w Twojej aplikacji i prosi o dodanie go do ekranu głównego.
- Aplikacja tworzy kanał i dodaje 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ł pojawia się w ostatnim wierszu ekranu głównego.
Kanał domyślny
Twoja 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 go zwykle wybrać i zatwierdzić. Każda aplikacja ma możliwość utworzenia 1 domyślnego kanału. Kanał domyślny jest wyjątkowy, ponieważ automatycznie pojawia się na ekranie głównym. Użytkownik nie musi o niego prosić.
Wymagania wstępne
Ekran główny Androida TV używa interfejsów API TvProvider Androida do zarządzania kanałami i programami tworzonymi przez Twoją aplikację. Aby uzyskać dostęp do danych dostawcy, dodaj do pliku manifestu aplikacji to uprawnienie:
<uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA" />
Biblioteka pomocy TvProvider ułatwia korzystanie z dostawcy. Dodaj ją do zależności w pliku build.gradle:
Dynamiczny
implementation 'androidx.tvprovider:tvprovider:1.0.0'
Kotlin
implementation("androidx.tvprovider:tvprovider:1.0.0")
Aby pracować z kanałami i programami, pamiętaj, aby w programie uwzględnić te instrukcje importu biblioteki pomocy:
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ę jej kanałem domyślnym. Kanał domyślny automatycznie pojawia się na ekranie głównym. Zanim inne utworzone przez Ciebie kanały pojawią się na ekranie głównym, użytkownik musi je wybrać i zaakceptować.
Tworzenie kanału
Aplikacja powinna prosić system o wyświetlanie nowo dodanych kanałów tylko wtedy, gdy działa na pierwszym planie. Zapobiega to wyświetlaniu przez aplikację okna z prośbą o zgodę na dodanie kanału, gdy użytkownik korzysta z innej aplikacji. Jeśli spróbujesz dodać kanał, gdy aplikacja działa w tle, metoda onActivityResult() działania zwróci kod stanu RESULT_CANCELED.
Aby utworzyć kanał:
Utwórz narzędzie do tworzenia kanałów i ustaw jego atrybuty. Pamiętaj, że typ 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());Aby później dodać programy do kanału, musisz zapisać identyfikator kanału. Wyodrębnij identyfikator kanału ze zwróconego URI:
Kotlin
var channelId = ContentUris.parseId(channelUri)Java
long channelId = ContentUris.parseId(channelUri);Musisz dodać logo kanału. Użyj
UrilubBitmap. Ikona logo powinna mieć wymiary 80 dp × 80 dp i musi być nieprzezroczysta. Jest wyświetlana 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 aplikacja utworzy pierwszy kanał, możesz ustawić go jako domyślny kanał, aby pojawił się na ekranie głównym od razu, bez żadnej interakcji użytkownika. Inne utworzone przez Ciebie kanały nie będą widoczne, dopóki użytkownik ich jawnie nie wybierze.
Kotlin
TvContractCompat.requestChannelBrowsable(context, channelId)Java
TvContractCompat.requestChannelBrowsable(context, channelId);Spraw, aby kanał domyślny pojawił się przed otwarciem aplikacji. Aby to zrobić, dodaj
BroadcastReceiver, który nasłuchuje działaniaandroid.media.tv.action.INITIALIZE_PROGRAMS. Ekran główny wysyła to działanie 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 nieoficjalnego źródła w trakcie programowania możesz przetestować ten krok, wywołując intencję za pomocą adb. W tym przypadku your.package.name/.YourReceiverName to
BroadcastReceiverTwojej aplikacji:adb shell am broadcast -a android.media.tv.action.INITIALIZE_PROGRAMS -n \ your.package.name/.YourReceiverNameW rzadkich przypadkach aplikacja może otrzymać transmisję w tym samym czasie, gdy użytkownik ją uruchamia. Upewnij się, że Twój kod nie próbuje dodać kanału domyślnego więcej niż raz.
Aktualizowanie kanału
Aktualizowanie kanałów jest bardzo podobne do ich tworzenia.
Użyj innego narzędzia Channel.Builder, aby ustawić atrybuty, które wymagają zmiany.
Aby zaktualizować kanał, użyj ContentResolver. Użyj identyfikatora kanału, który został zapisany 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
Programy to poszczególne karty treści wyświetlane na kanale. Możesz publikować programy zarówno na niestandardowych kanałach aplikacji, jak i na zarządzanym przez system kanale Warte obejrzenia.
Dodawanie programów do kanału aplikacji
Utwórz narzędzie 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. (Atrybuty dostępne dla każdego typu 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, aby móc się do niego później odwoływać:
Kotlin
val programId = ContentUris.parseId(programUri)
Java
long programId = ContentUris.parseId(programUri);
Dodawanie programów do kanału Warte obejrzenia
Aby wstawić programy do kanału Warte obejrzenia, przeczytaj sekcję Dodawanie programów do kanału Warte obejrzenia.
Aktualizowanie programu
Możesz zmienić informacje o programie. Możesz na przykład zaktualizować cenę wypożyczenia filmu lub pasek postępu pokazujący, ile programu użytkownik obejrzał.
Użyj narzędzia PreviewProgram.Builder, aby ustawić atrybuty, które chcesz zmienić, a następnie wywołaj getContentResolver().update, aby zaktualizować program. Określ identyfikator programu, który został 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 Twoimi kanałami po ich pojawieniu się na ekranie głównym.
Odkrywanie i dodawanie kanałów
Twoja aplikacja może udostępniać element interfejsu, który umożliwia użytkownikowi wybieranie i dodawanie kanałów (np. przycisk z prośbą o dodanie kanału).
Gdy użytkownik poprosi o konkretny kanał, wykonaj ten kod, aby uzyskać jego zgodę na dodanie kanału 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świetla okno z prośbą o zatwierdzenie kanału. Obsłuż wynik żądania w metodzie onActivityResult działania (Activity.RESULT_CANCELED lub Activity.RESULT_OK).
Zdarzenia ekranu głównego Androida TV
Gdy użytkownik wchodzi w interakcję z programami i kanałami opublikowanymi przez aplikację, ekran główny wysyła do aplikacji intencje:
- Gdy użytkownik wybierze logo kanału, ekran główny wyśle do aplikacji adres
Urizapisany w atrybucie APP_LINK_INTENT_URI kanału. Aplikacja powinna po prostu uruchomić swój główny interfejs lub widok związany z wybranym kanałem. - Gdy użytkownik wybierze program, ekran główny wyśle do aplikacji adres
Urizapisany w atrybucie INTENT_URI programu. Aplikacja powinna odtworzyć wybraną treść. - Użytkownik może wskazać, że nie jest już zainteresowany programem i chce go usunąć z interfejsu ekranu głównego. System usuwa program z interfejsu i wysyła do aplikacji, która jest właścicielem programu, 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 z dostawcy i NIE powinna go ponownie wstawiać.
Pamiętaj, aby utworzyć filtry intencji dla wszystkich Uris, które ekran główny
wysyła w przypadku interakcji użytkownika. 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>
Uwagi dodatkowe
- Wiele aplikacji telewizyjnych wymaga, aby użytkownicy się logowali. W takim przypadku
BroadcastReceiver, który nasłuchujeandroid.media.tv.action.INITIALIZE_PROGRAMS, powinien sugerować treści kanału użytkownikom, którzy nie są uwierzytelnieni. Aplikacja może na przykład początkowo wyświetlać najlepsze lub obecnie popularne treści. Po zalogowaniu się użytkownika może wyświetlać treści spersonalizowane. To świetna okazja dla aplikacji, aby zachęcić użytkowników do zakupu przed zalogowaniem. - Gdy aplikacja nie jest na pierwszym planie i musisz zaktualizować kanał lub
program, użyj
JobScheduler, aby zaplanować pracę (patrzJobScheduleriJobService). - Jeśli aplikacja działa nieprawidłowo (np. ciągle wysyła do dostawcy spam z danymi), system może cofnąć jej uprawnienia dostawcy. Pamiętaj, aby otoczyć kod, który uzyskuje dostęp do dostawcy, klauzulami try-catch, aby obsługiwać wyjątki związane z bezpieczeństwem.
Zanim zaktualizujesz programy i kanały, zapytaj dostawcę o dane, które chcesz zaktualizować, i uzgodnij je. Nie ma na przykład potrzeby aktualizowania programu, który użytkownik chce usunąć z interfejsu. Użyj zadania w tle, które wstawia lub aktualizuje dane w dostawcy po zapytaniu o istniejące dane i poproszeniu o zatwierdzenie kanałów. Możesz uruchamiać to zadanie, gdy aplikacja się uruchamia i gdy musi zaktualizować swoje 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 adresów URI dla wszystkich obrazów (logo, ikon, obrazów treści). Pamiętaj, aby podczas aktualizowania obrazu używać innego adresu URI. Wszystkie obrazy są buforowane. Jeśli nie zmienisz adresu URI podczas zmiany obrazu, stary obraz będzie nadal się wyświetlać.
Pamiętaj, że klauzule WHERE są niedozwolone, a wywołania dostawców z klauzulami WHERE spowodują zgłoszenie wyjątku związanego z bezpieczeństwem.
Atrybuty
W tej sekcji opisujemy osobno atrybuty kanału i programu.
Atrybuty kanału
W przypadku każdego kanału musisz określić te atrybuty:
| Atrybut | Uwagi |
|---|---|
| TYP | ustaw na TYPE_PREVIEW. |
| DISPLAY_NAME | ustaw na nazwę kanału. |
| APP_LINK_INTENT_URI | Gdy użytkownik wybierze logo kanału, system wyśle intencję uruchomienia działania, które prezentuje treści związane z kanałem. Ustaw ten atrybut na adres URI używany w filtrze intencji dla tego działania. |
Kanał ma też 6 pól zarezerwowanych do użytku wewnętrznego aplikacji. Te pola mogą służyć do przechowywania kluczy lub innych wartości, które mogą pomóc aplikacji w mapowaniu kanału na jego wewnętrzną strukturę danych:
- INTERNAL_PROVIDER_ID
- INTERNAL_PROVIDER_DATA
- INTERNAL_PROVIDER_FLAG1
- INTERNAL_PROVIDER_FLAG2
- INTERNAL_PROVIDER_FLAG3
- INTERNAL_PROVIDER_FLAG4
Atrybuty programu
Informacje o atrybutach każdego typu programu znajdziesz na poszczególnych stronach:
- Atrybuty programu wideo
- Atrybuty programu audio
- Atrybuty programu gry
- Atrybuty programu Warte obejrzenia
Przykładowy kod
Aby dowiedzieć się więcej o tworzeniu aplikacji, które wchodzą w interakcje z ekranem głównym i dodają kanały oraz programy do ekranu głównego Androida TV, zapoznaj się z naszym codelabem dotyczącym ekranu głównego .