Usługa wejścia TV reprezentuje źródło strumienia multimediów i umożliwia prezentowanie treści multimedialnych linearnych, naziemnych kanałów i programów. Usługa wejścia TV umożliwia kontrola rodzicielska, informacje w przewodniku po programie i oceny treści. Usługa wejścia TV działa w aplikacji systemowej Android TV. Ta aplikacja ostatecznie kontroluje i prezentuje zawartość kanału na telewizorze. Systemowa aplikacja TV została opracowana specjalnie dla danego urządzenia i nie można przez aplikacje innych firm. Więcej informacji o platformie wejściowej TV (TIF) architektury i jej komponentów, zobacz Platforma wejścia TV.
Tworzenie usługi wejścia TV przy użyciu biblioteki towarzyszącej TIF
Biblioteka towarzysząca TIF to platforma, która udostępnia implementacji typowych funkcji usługi wejścia TV. Ma być wykorzystywana przez OEM do tworzenia i tylko na urządzeniach z Androidem w wersji od 5.0 (poziom interfejsu API 21) do 7.1 (poziom interfejsu API 25).
Zaktualizuj projekt
Biblioteka towarzysząca TIF jest dostępna do starszych wersji przez producentów OEM w androidtv-sample-inputs z repozytorium. Znajdziesz w nim przykład, jak umieścić bibliotekę w aplikacji.
Zadeklaruj w pliku manifestu usługę wejścia TV
Aplikacja musi udostępniać interfejs zgodny z TvInputService
usługa, za pomocą której system uzyskuje dostęp do aplikacji. TIF-y
Biblioteka towarzysząca udostępnia klasę BaseTvInputService
, która
zapewnia domyślną implementację tagu TvInputService
które możesz dostosować. Utwórz podklasę BaseTvInputService
,
i zadeklaruj w pliku manifestu podklasę jako usługę.
W deklaracji pliku manifestu podaj
BIND_TV_INPUT
, aby zezwolić na
służą do podłączenia wejścia TV do systemu. Usługa systemowa
wykonuje wiązanie i ma
Uprawnienie BIND_TV_INPUT
.
Systemowa aplikacja TV wysyła żądania do usług wejścia TV
w interfejsie TvInputManager
.
W deklaracji dotyczącej usługi umieść filtr intencji, który określa
TvInputService
jako działanie do wykonania z
intencji. Zadeklaruj także metadane usługi jako oddzielny zasób XML.
wyświetlana jest deklaracja dotycząca usługi, filtr intencji i deklaracja metadanych usługi
w tym przykładzie:
<service android:name=".rich.RichTvInputService" android:label="@string/rich_input_label" android:permission="android.permission.BIND_TV_INPUT"> <!-- Required filter used by the system to launch our account service. --> <intent-filter> <action android:name="android.media.tv.TvInputService" /> </intent-filter> <!-- An XML file which describes this input. This provides pointers to the RichTvInputSetupActivity to the system/TV app. --> <meta-data android:name="android.media.tv.input" android:resource="@xml/richtvinputservice" /> </service>
Zdefiniuj metadane usługi w osobnym pliku XML. Usługa Plik XML metadanych musi zawierać interfejs konfiguracyjny opisujący konfigurację początkową i skanowanie kanałów. Plik metadanych powinien też zawierać atrybut z informacją, czy użytkownicy mogą nagrywać treści. Więcej na temat obsługi nagrywania treści w aplikacji można znaleźć w artykule Obsługa nagrywania treści.
Plik metadanych usługi znajduje się w katalogu zasobów XML
dla Twojej aplikacji i musi być zgodna z nazwą zasobu zadeklarowanego w
pliku manifestu. Korzystając z wpisów w pliku manifestu z poprzedniego przykładu:
utworzymy plik XML pod adresem res/xml/richtvinputservice.xml
, z klasą
ta treść:
<?xml version="1.0" encoding="utf-8"?> <tv-input xmlns:android="http://schemas.android.com/apk/res/android" android:canRecord="true" android:setupActivity="com.example.android.sampletvinput.rich.RichTvInputSetupActivity" />
Zdefiniuj kanały i utwórz aktywność związaną z konfiguracją
Usługa wejścia TV musi definiować co najmniej jeden kanał, na którym użytkownicy za pomocą systemowej aplikacji TV. Zarejestruj swoje kanały w bazie danych systemu i udostępnić działanie konfiguracyjne, wywołuje, gdy nie może znaleźć kanału dla Twojej aplikacji.
Najpierw zezwól aplikacji na odczyt i zapis w systemie elektronicznym Przewodnik dla programistów (EPG), którego dane obejmują dostępne kanały i programy po stronie użytkownika. Aby umożliwić aplikacji wykonywanie tych działań, i przeprowadź synchronizację z Po ponownym uruchomieniu urządzenia dodaj te elementy do pliku manifestu aplikacji:
<uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED "/>
Dodaj ten element, aby mieć pewność, że Twoja aplikacja będzie widoczna w Sklep Google Play jako aplikacja do udostępniania kanałów z treściami na Androidzie TV:
<uses-feature android:name="android.software.live_tv" android:required="true" />
Następnie utwórz zajęcia, które rozszerzą EpgSyncJobService
zajęcia. Ta klasa abstrakcyjna ułatwia utworzenie usługi zadań, która
tworzy i aktualizuje kanały w systemowej bazie danych.
W podklasie utwórz i zwróć pełną listę kanałów w
getChannels()
Jeśli kanały pochodzą z pliku XMLTV,
użyj klasy XmlTvParser
. W przeciwnym razie wygeneruj
kanałów automatycznie za pomocą klasy Channel.Builder
.
W przypadku każdego kanału system wywołuje funkcję getProgramsForChannel()
gdy potrzebna jest lista programów, które można wyświetlić w danym przedziale czasu.
na kanale. Zwraca listę obiektów Program
dla argumentu
kanał. Używaj klasy XmlTvParser
, aby uzyskiwać programy z
XMLTV ani
wygenerować go automatycznie przy użyciu
Program.Builder
zajęcia.
W przypadku każdego obiektu Program
użyj
InternalProviderData
, aby ustawić informacje o programie, takie jak
typu wideo programu. Jeśli masz tylko ograniczoną liczbę programów,
chcesz, aby kanał powtarzał się w pętli, użyj
Metoda InternalProviderData.setRepeatable()
o wartości
true
podczas podawania informacji o programie.
Po wdrożeniu usługi zadań dodaj ją do pliku manifestu aplikacji:
<service android:name=".sync.SampleJobService" android:permission="android.permission.BIND_JOB_SERVICE" android:exported="true" />
Na koniec utwórz aktywność związaną z konfiguracją. Aktywność związana z konfiguracją powinna dać Ci możliwość aby zsynchronizować dane dotyczące kanału i programu. Użytkownik może to zrobić np. za pomocą interfejsu użytkownika w ramach aktywności. Możliwe też, że aplikacja robi to automatycznie. po rozpoczęciu aktywności. Kiedy aktywność związana z konfiguracją musi zsynchronizować kanał informacje o programie, aplikacja powinna uruchamiać usługę zadań:
Kotlin
val inputId = getActivity().intent.getStringExtra(TvInputInfo.EXTRA_INPUT_ID) EpgSyncJobService.cancelAllSyncRequests(getActivity()) EpgSyncJobService.requestImmediateSync( getActivity(), inputId, ComponentName(getActivity(), SampleJobService::class.java) )
Java
String inputId = getActivity().getIntent().getStringExtra(TvInputInfo.EXTRA_INPUT_ID); EpgSyncJobService.cancelAllSyncRequests(getActivity()); EpgSyncJobService.requestImmediateSync(getActivity(), inputId, new ComponentName(getActivity(), SampleJobService.class));
Do synchronizacji używaj metody requestImmediateSync()
z usługą zadań. Użytkownik musi poczekać na zakończenie synchronizacji, więc
staraj się utrzymać względnie krótki okres przesyłania zgłoszeń.
Aby udostępnić usługę zadania, użyj metody setUpPeriodicSync()
okresowo synchronizują dane dotyczące kanałów i programu w tle:
Kotlin
EpgSyncJobService.setUpPeriodicSync( context, inputId, ComponentName(context, SampleJobService::class.java) )
Java
EpgSyncJobService.setUpPeriodicSync(context, inputId, new ComponentName(context, SampleJobService.class));
Biblioteka towarzysząca TIF zapewnia dodatkową, przeciążoną metodę
requestImmediateSync()
, który pozwala określić czas trwania
do synchronizacji danych kanału w milisekundach. Domyślna metoda synchronizuje 1 godzinę
na podstawie danych kanału.
Biblioteka towarzysząca TIF zapewnia również dodatkową, przeciążoną metodę
setUpPeriodicSync()
, który pozwala określić czas trwania
dane o kanale, które mają być synchronizowane, oraz jak często ma być przeprowadzana synchronizacja okresowa.
Domyślna metoda synchronizuje dane kanału z 48 godzin co 12 godzin.
Więcej informacji o danych kanału i EPG znajdziesz na stronie Praca z danymi kanału.
Obsługa żądań dostrajania i odtwarzania multimediów
Gdy użytkownik wybierze określony kanał, systemowa aplikacja TV użyje
Session
, utworzone przez Twoją aplikację, aby dostroić wybrany kanał
i odtwarzać treści. Biblioteka towarzysząca TIF obejmuje kilka
klas, które można rozszerzyć na obsługę wywołań kanałów i sesji z systemu.
Twoja podklasa BaseTvInputService
tworzy sesje, które obsługują
żądań dostrajania. Zastąp
onCreateSession()
, utwórz sesję rozszerzoną z
klasę BaseTvInputService.Session
i wywołanie
super.sessionCreated()
z nową sesją. W następujących
przykład onCreateSession()
zwraca
RichTvInputSessionImpl
obiekt, który rozciąga się
BaseTvInputService.Session
:
Kotlin
override fun onCreateSession(inputId: String): Session = RichTvInputSessionImpl(this, inputId).apply { setOverlayViewEnabled(true) }
Java
@Override public final Session onCreateSession(String inputId) { RichTvInputSessionImpl session = new RichTvInputSessionImpl(this, inputId); session.setOverlayViewEnabled(true); return session; }
Gdy użytkownik zacznie oglądać jeden z Twoich kanałów w systemowej aplikacji TV,
system wywołuje metodę onPlayChannel()
sesji. Zastąp
Jeśli musisz zainicjować jakiś kanał specjalnie przed
rozpocznie się odtwarzanie programu.
Następnie system pobiera aktualnie zaplanowany program i wywołuje
metody onPlayProgram()
sesji, określającą program
i czas rozpoczęcia w milisekundach. Użyj
TvPlayer
, aby rozpocząć odtwarzanie programu.
Kod odtwarzacza powinien implementować TvPlayer
, aby obsługiwać
określonych zdarzeń związanych z odtwarzaniem. Klasa TvPlayer
obsługuje funkcje
np. elementy sterujące przesuwaniem w czasie,
które nie zwiększą złożoności
BaseTvInputService
.
W metodzie getTvPlayer()
sesji funkcję zwracaj
odtwarzacz, który obsługuje TvPlayer
.
Przykładowa aplikacja związana z usługą wejścia TV implementuje odtwarzacz multimedialny, który używa
ExoPlayer,
Utwórz usługę wejścia TV przy użyciu struktury wejścia TV
Jeśli usługa wejścia TV nie może korzystać z biblioteki towarzyszącej TIF, wymagane jest do implementacji tych komponentów:
TvInputService
zapewnia długoterminową dostępność i dostępność w tle dla wejście TVTvInputService.Session
utrzymuje stan wejścia TV i komunikuje się z aplikacją hostującąTvContract
opisuje kanały i programy dostępne na telewizorze. dane wejścioweTvContract.Channels
podaje informacje o kanale telewizyjnymTvContract.Programs
opisuje program telewizyjny z takimi danymi jak program tytuł i godzina rozpoczęciaTvTrackInfo
oznacza ścieżkę audio, wideo lub napisy.TvContentRating
opisuje ocenę treści, dopuszcza własne treści systemy ocenTvInputManager
udostępnia interfejs API systemowej aplikacji TV i zarządza interakcje z wejściami i aplikacjami TV
Musisz też wykonać te czynności:
- W pliku manifestu zadeklaruj usługę wejścia TV jako opisane w sekcji Zadeklaruj usługę wejścia TV w pliku manifestu.
- Utwórz plik metadanych usługi.
- Utwórz i zarejestruj informacje o kanale i programie.
- Utwórz aktywność związaną z konfiguracją.
Zdefiniuj usługę wejścia TV
W przypadku swojej usługi przedłużasz klasę TvInputService
. O
Implementacja TvInputService
jest
powiązana usługa, w której usługa systemowa
to klient, który z nią wiąże. Metody cyklu życia usługi
który trzeba wdrożyć, przedstawiono na rysunku 1.
Metoda onCreate()
inicjuje i uruchamia
HandlerThread
, który zapewnia wątek procesu oddzielny od wątku UI do
i obsługiwać
działania systemowe. W poniższym przykładzie onCreate()
inicjuje CaptioningManager
i przygotowuje się do obsługi
ACTION_BLOCKED_RATINGS_CHANGED
i ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED
czynności. Te
działania opisują intencje systemowe uruchamiane, gdy użytkownik zmieni ustawienia kontroli rodzicielskiej oraz kiedy
lista zablokowanych ocen uległa zmianie.
Kotlin
override fun onCreate() { super.onCreate() handlerThread = HandlerThread(javaClass.simpleName).apply { start() } dbHandler = Handler(handlerThread.looper) handler = Handler() captioningManager = getSystemService(Context.CAPTIONING_SERVICE) as CaptioningManager setTheme(android.R.style.Theme_Holo_Light_NoActionBar) sessions = mutableListOf<BaseTvInputSessionImpl>() val intentFilter = IntentFilter().apply { addAction(TvInputManager.ACTION_BLOCKED_RATINGS_CHANGED) addAction(TvInputManager.ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED) } registerReceiver(broadcastReceiver, intentFilter) }
Java
@Override public void onCreate() { super.onCreate(); handlerThread = new HandlerThread(getClass() .getSimpleName()); handlerThread.start(); dbHandler = new Handler(handlerThread.getLooper()); handler = new Handler(); captioningManager = (CaptioningManager) getSystemService(Context.CAPTIONING_SERVICE); setTheme(android.R.style.Theme_Holo_Light_NoActionBar); sessions = new ArrayList<BaseTvInputSessionImpl>(); IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(TvInputManager .ACTION_BLOCKED_RATINGS_CHANGED); intentFilter.addAction(TvInputManager .ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED); registerReceiver(broadcastReceiver, intentFilter); }
![](https://developer.android.com/static/images/tv/tvinput-life.png?authuser=9&hl=pl)
Rysunek 1. Cykl życia usługi TvInputService.
Zobacz
Zarządzaj treściami, aby uzyskać więcej informacji o pracy z zablokowanymi treściami i udostępnianiu
kontrolę rodzicielską. Na stronie TvInputManager
znajdziesz więcej działań opartych na systemie, które
może być obsługiwane w usłudze wejścia TV.
TvInputService
tworzy
TvInputService.Session
z implementacją Handler.Callback
do obsługi zmian stanu odtwarzacza. Na
onSetSurface()
,
TvInputService.Session
ustawia Surface
z
treści wideo. Patrz artykuł Integrowanie odtwarzacza z platformą.
, aby dowiedzieć się więcej o używaniu tagu Surface
do renderowania filmu.
TvInputService.Session
obsługuje
onTune()
gdy użytkownik wybierze kanał i powiadomi systemową aplikację TV o zmianach w treści oraz
metadanych treści. Te metody notify()
zostały opisane tutaj:
Kontrolowanie treści i wyboru ścieżki obsługi
w dalszej części tego szkolenia.
Zdefiniuj aktywność związaną z konfiguracją
Systemowa aplikacja TV korzysta z określonych przez Ciebie czynności związanych z konfiguracją wejścia TV. aktywność związana z konfiguracją jest wymagana i musi zapewniać co najmniej 1 rekord kanału dla systemowej bazy danych. Aplikacja systemowa TV wywołuje aktywność konfiguracyjne, gdy nie może znaleźć kanału dla wejścia TV.
Działanie związane z konfiguracją opisuje w systemowej aplikacji TV kanały udostępnione na telewizorze jak widać w następnej lekcji – Tworzenie i edytowanie danych, i zaktualizuj dane o kanałach.