Layanan input TV merepresentasikan sumber streaming media, dan memungkinkan Anda menyajikan konten media secara linear dan menyiarkan TV sebagai saluran dan program. Dengan layanan input TV, Anda dapat menyediakan kontrol orang tua, informasi panduan program, dan rating konten. Layanan input TV berfungsi dengan aplikasi TV yang ada pada sistem Android. Pada akhirnya, aplikasi ini mengontrol dan menyajikan konten saluran di TV. Aplikasi TV sistem dikembangkan khusus untuk perangkat dan tidak dapat diubah oleh aplikasi pihak ketiga. Untuk informasi selengkapnya tentang arsitektur Framework Input TV (TIF) dan komponennya, lihat Framework Input TV.
Membuat layanan input TV menggunakan Library Pendamping TIF
Library Pendamping TIF adalah framework yang menyediakan implementasi yang dapat diperluas untuk fitur layanan input TV umum. Fitur ini hanya digunakan oleh OEM untuk membuat saluran hanya untuk Android 5.0 (API level 21) hingga Android 7.1 (API level 25).
Mengupdate project Anda
Library Pendamping TIF tersedia untuk penggunaan lama oleh OEM di repositori androidtv-sample-inputs. Lihat repositori tersebut untuk mengetahui contoh cara menyertakan library dalam aplikasi.
Mendeklarasikan layanan input TV dalam manifes
Aplikasi Anda harus menyediakan layanan yang kompatibel dengan TvInputService
yang digunakan sistem untuk mengakses aplikasi Anda. Library
Pendamping TIF menyediakan class BaseTvInputService
, yang
menyediakan implementasi default TvInputService
yang dapat Anda sesuaikan. Buat subclass dari BaseTvInputService
,
dan deklarasikan subclass tersebut ke dalam manifes Anda sebagai layanan.
Di dalam deklarasi manifes, tentukan
izin BIND_TV_INPUT
untuk mengizinkan
layanan menghubungkan input TV ke sistem. Layanan sistem
melakukan binding dan memiliki
izin BIND_TV_INPUT
.
Aplikasi TV yang ada pada sistem mengirimkan permintaan ke layanan input TV
melalui antarmuka TvInputManager
.
Dalam deklarasi layanan, sertakan filter intent yang menentukan
TvInputService
sebagai tindakan yang akan dilakukan dengan
intent tersebut. Deklarasikan juga metadata layanan sebagai resource XML yang terpisah. Deklarasi
layanan, filter intent, dan deklarasi metadata layanan ditampilkan
dalam contoh berikut:
<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>
Tentukan metadata layanan dalam file XML terpisah. File XML metadata layanan harus menyertakan antarmuka penyiapan yang menjelaskan konfigurasi awal input TV dan pemindaian saluran. File metadata juga harus berisi flag yang menyatakan apakah pengguna dapat merekam konten atau tidak. Untuk mengetahui informasi selengkapnya tentang cara mendukung konten rekaman di aplikasi, lihat Mendukung perekaman konten.
File metadata layanan terletak di direktori resource XML
untuk aplikasi Anda dan harus cocok dengan nama resource yang Anda deklarasikan dalam
manifes. Dengan menggunakan entri manifes dari contoh sebelumnya, Anda akan
membuat file XML di res/xml/richtvinputservice.xml
, dengan
konten berikut:
<?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" />
Menentukan saluran dan membuat aktivitas setelan Anda
Layanan input TV Anda harus menentukan setidaknya satu saluran yang diakses pengguna melalui aplikasi TV yang ada pada sistem. Anda harus mendaftarkan saluran dalam database sistem, dan menyediakan aktivitas penyiapan yang dipanggil sistem saat tidak dapat menemukan saluran untuk aplikasi Anda.
Pertama, aktifkan aplikasi Anda untuk membaca dan menulis ke Electronic Programming Guide (EPG) sistem, yang datanya mencakup berbagai saluran dan program yang tersedia bagi pengguna. Agar aplikasi Anda dapat melakukan tindakan ini dan menyinkronkan dengan EPG setelah perangkat dimulai ulang, tambahkan elemen berikut ke manifes aplikasi:
<uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED "/>
Tambahkan elemen berikut untuk memastikan aplikasi Anda muncul di Google Play Store sebagai aplikasi yang menyediakan saluran konten di Android TV:
<uses-feature android:name="android.software.live_tv" android:required="true" />
Selanjutnya, buat class yang memperluas class
EpgSyncJobService
. Class abstrak ini memudahkan pembuatan layanan tugas yang
membuat dan mengupdate saluran di database sistem.
Di subclass Anda, buat dan tampilkan daftar lengkap saluran di
getChannels()
. Jika saluran Anda berasal dari file XMLTV,
gunakan class XmlTvParser
. Jika tidak, buat
saluran secara terprogram menggunakan class Channel.Builder
.
Untuk setiap saluran, sistem akan memanggil getProgramsForChannel()
saat memerlukan daftar program yang dapat dilihat dalam jangka waktu tertentu
pada saluran. Tampilkan daftar objek Program
untuk
saluran. Gunakan class XmlTvParser
untuk mendapatkan program dari
file XMLTV, atau buat secara terprogram menggunakan
class Program.Builder
.
Untuk setiap objek Program
, gunakan
objek InternalProviderData
untuk menyetel informasi program seperti
jenis video program. Jika Anda hanya memiliki sejumlah program tertentu yang
ingin diulangi oleh saluran tersebut dalam sebuah loop, gunakan
metode InternalProviderData.setRepeatable()
dengan nilai
true
saat menetapkan informasi tentang program Anda.
Setelah selesai mengimplementasikan layanan tugas, tambahkan layanan tugas ke manifes aplikasi:
<service android:name=".sync.SampleJobService" android:permission="android.permission.BIND_JOB_SERVICE" android:exported="true" />
Terakhir, buat aktivitas penyiapan. Aktivitas penyiapan Anda harus menyediakan cara untuk menyinkronkan data saluran dan program. Salah satu cara untuk melakukannya adalah meminta pengguna melakukannya melalui UI dalam aktivitas. Anda juga dapat membuat aplikasi melakukannya secara otomatis saat aktivitas dimulai. Saat aktivitas penyiapan perlu menyinkronkan info saluran dan program, aplikasi harus memulai layanan tugas:
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));
Gunakan metode requestImmediateSync()
untuk menyinkronkan
layanan tugas. Pengguna harus menunggu sinkronisasi selesai, jadi Anda harus
mempertahankan periode permintaan Anda relatif singkat.
Gunakan metode setUpPeriodicSync()
agar layanan tugas
menyinkronkan saluran dan data program secara berkala di latar belakang:
Kotlin
EpgSyncJobService.setUpPeriodicSync( context, inputId, ComponentName(context, SampleJobService::class.java) )
Java
EpgSyncJobService.setUpPeriodicSync(context, inputId, new ComponentName(context, SampleJobService.class));
Library Pendamping TIF menyediakan metode overload tambahan dari
requestImmediateSync()
yang memungkinkan Anda menentukan durasi
sinkronisasi data saluran dalam milidetik. Metode default menyinkronkan data saluran
selama satu jam.
Library Pendamping TIF juga menyediakan metode overload tambahan,
setUpPeriodicSync()
, yang memungkinkan Anda menentukan durasi
sinkronisasi data saluran, dan seberapa sering sinkronisasi berkala harus terjadi. Metode default menyinkronkan 48 jam data saluran setiap 12 jam.
Untuk mengetahui detail data saluran dan EPG lebih lanjut, lihat Bekerja dengan data saluran.
Menangani permintaan tuning dan pemutaran media
Saat pengguna memilih saluran tertentu, aplikasi TV yang ada pada sistem akan menggunakan
Session
yang dibuat oleh aplikasi Anda untuk menyetel ke saluran yang diminta
dan memutar konten. Library Pendamping TIF menyediakan beberapa
class yang dapat diperluas untuk menangani panggilan saluran dan sesi dari sistem.
Subclass BaseTvInputService
Anda membuat sesi yang menangani
permintaan tuning. Ganti
metode onCreateSession()
, buat sesi yang diperluas dari
class BaseTvInputService.Session
, lalu panggil
super.sessionCreated()
dengan sesi baru Anda. Dalam contoh
berikut, onCreateSession()
menampilkan
objek RichTvInputSessionImpl
yang memperluas
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; }
Saat pengguna menggunakan aplikasi TV sistem untuk mulai melihat salah satu saluran Anda,
sistem akan memanggil metode onPlayChannel()
sesi Anda. Ganti
metode ini jika Anda perlu melakukan inisialisasi saluran khusus sebelum
program mulai diputar.
Sistem kemudian mendapatkan program yang saat ini dijadwalkan dan memanggil
metode onPlayProgram()
sesi Anda serta menentukan informasi
program dan waktu mulai dalam milidetik. Gunakan
antarmuka TvPlayer
untuk mulai memutar program.
Kode pemutar media Anda harus menerapkan TvPlayer
untuk menangani
peristiwa pemutaran tertentu. Class TvPlayer
menangani fitur
seperti kontrol pergeseran waktu tanpa menambah kompleksitas
pada implementasi BaseTvInputService
.
Dalam metode getTvPlayer()
sesi, tampilkan
pemutar media yang mengimplementasikan TvPlayer
. Aplikasi contoh
Layanan Input TV mengimplementasikan media player yang menggunakan
ExoPlayer.
Membuat layanan input TV menggunakan framework input TV
Jika layanan input TV Anda tidak dapat menggunakan Library Pendamping TIF, Anda harus mengimplementasikan komponen berikut:
TvInputService
menyediakan ketersediaan input TV yang berjalan lama dan berjalan di latar belakangTvInputService.Session
mempertahankan status input TV dan berkomunikasi dengan aplikasi hostingTvContract
mendeskripsikan saluran dan program yang tersedia untuk input TVTvContract.Channels
merepresentasikan informasi tentang saluran TVTvContract.Programs
mendeskripsikan program TV dengan data seperti judul program dan waktu mulaiTvTrackInfo
merepresentasikan trek subtitel, audio, atau videoTvContentRating
mendeskripsikan rating konten, memungkinkan skema rating konten kustomTvInputManager
menyediakan API ke aplikasi TV yang ada pada sistem dan mengelola interaksi dengan input TV dan aplikasi
Anda juga perlu melakukan yang berikut ini:
- Deklarasikan layanan input TV Anda dalam manifes, seperti yang dijelaskan dalam Mendeklarasikan layanan input TV Anda dalam manifes.
- Buat file metadata layanan.
- Buat dan daftarkan informasi saluran dan program Anda.
- Buat aktivitas penyiapan Anda.
Menentukan layanan input TV Anda
Untuk layanan Anda, perluas class TvInputService
. Implementasi
TvInputService
adalah
layanan terikat dengan layanan sistem
adalah klien yang mengikatnya. Metode siklus proses layanan
yang perlu Anda implementasikan diilustrasikan dalam gambar 1.
Metode onCreate()
menginisialisasi dan memulai
HandlerThread
yang menyediakan thread proses yang terpisah dari UI thread untuk
menangani tindakan berbasis sistem. Pada contoh berikut, metode onCreate()
menginisialisasi CaptioningManager
dan bersiap untuk menangani
tindakan ACTION_BLOCKED_RATINGS_CHANGED
dan ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED
. Tindakan
ini menjelaskan intent sistem yang diaktifkan saat pengguna mengubah setelan kontrol orang tua, dan saat
ada perubahan pada daftar rating yang diblokir.
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); }
Lihat
Konten kontrol untuk mengetahui informasi selengkapnya tentang cara menangani konten yang diblokir dan memberikan
kontrol orang tua. Lihat TvInputManager
untuk tindakan berbasis sistem lainnya yang
mungkin ingin Anda tangani di layanan input TV.
TvInputService
membuat
TvInputService.Session
yang mengimplementasikan Handler.Callback
untuk menangani perubahan status pemutar. Dengan
onSetSurface()
,
TvInputService.Session
menyetel Surface
dengan
konten video. Lihat Mengintegrasikan pemutar dengan permukaan
untuk mengetahui informasi selengkapnya tentang menggunakan Surface
untuk merender video.
TvInputService.Session
menangani peristiwa
onTune()
saat pengguna memilih saluran, dan memberi tahu aplikasi TV yang ada pada sistem untuk mengubah konten dan
metadata konten. Metode notify()
ini dijelaskan lebih lanjut di
Mengontrol Konten dan Menangani pemilihan trek
dalam pelatihan ini.
Mendefinisikan aktivitas penyiapan Anda
Aplikasi TV yang ada pada sistem berjalan dengan aktivitas penyiapan yang Anda tentukan untuk input TV Anda. Aktivitas penyiapan diperlukan dan harus menyediakan setidaknya satu data saluran untuk database sistem. Aplikasi TV yang ada pada sistem akan memanggil aktivitas penyiapan saat tidak dapat menemukan saluran untuk input TV.
Aktivitas penyiapan menjelaskan saluran yang disediakan melalui input TV kepada aplikasi TV yang ada pada sistem, seperti yang ditunjukkan di tutorial berikutnya, Membuat dan mengupdate data saluran.