Layanan input TV merepresentasikan sumber streaming media, dan memungkinkan Anda menyajikan konten media Anda dengan metode siaran TV linear sebagai saluran dan program. Dengan layanan input TV, Anda dapat memberikan kontrol orang tua, informasi panduan program, dan rating konten. Layanan input TV dapat digunakan dengan aplikasi TV yang ada pada sistem Android. Pada dasarnya, aplikasi ini mengontrol dan menyajikan konten saluran di TV. Aplikasi TV yang ada pada sistem secara khusus dikembangkan untuk perangkat dan tidak dapat diubah oleh aplikasi pihak ketiga. Untuk mengetahui informasi selengkapnya mengenai arsitektur dan komponen Framework Input TV (TIF), lihat Framework Input TV.
Membuat layanan input TV menggunakan Library Pendamping TIF
Library Pendamping TIF adalah framework yang menyediakan implementasi yang dapat diperluas dari fitur layanan input TV umum. Gunakan Library Pendamping TIF untuk membuat layanan input TV Anda sendiri dengan cepat dan mudah yang mengikuti praktik terbaik Android TV.
Mengupdate project Anda
Untuk memulai menggunakan Library Pendamping TIF, tambahkan kode berikut ke file build.gradle
aplikasi Anda:
compile 'com.google.android.libraries.tv:companionlibrary:0.2'
Library Pendamping TIF saat ini bukan bagian dari framework Android. Library Pendamping TIF didistribusikan sebagai dependensi Gradle melalui jcenter, bukan melalui Android SDK. Periksa jcenter untuk menemukan versi terbaru dari library tif-companion.
Mendeklarasikan layanan input TV dalam manifes
Aplikasi Anda harus menyediakan layanan yang kompatibel dengan TvInputService
yang digunakan oleh sistem untuk mengakses aplikasi Anda. Library Pendamping TIF menyediakan class BaseTvInputService
, yang menyediakan implementasi default dari 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 agar menghubungkan input TV ke sistem. Layanan sistem menjalankan binding dan memiliki izin BIND_TV_INPUT
.
Aplikasi TV yang ada pada sistem mengirimkan permintaan ke layanan masukan TV melalui antarmuka TvInputManager
.
Dalam deklarasi layanan Anda, sertakan filter intent yang menentukan TvInputService
sebagai tindakan yang akan dijalankan bersama intent. 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 penyetelan yang menjelaskan pemindaian saluran dan konfigurasi awal input TV. 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 Anda, lihat Rekaman TV.
File layanan metadata terletak di direktori resource XML untuk aplikasi Anda dan harus sesuai dengan nama resource yang Anda deklarasikan di manifes. Dengan menggunakan entri manifes dari contoh sebelumnya, sebaiknya buat 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 mendefinisikan sedikitnya satu saluran yang diakses pengguna melalui aplikasi TV yang ada pada sistem. Anda harus mendaftarkan saluran di dalam database sistem, dan menyediakan aktivitas penyiapan yang dipanggil sistem saat tidak dapat menemukan saluran apa pun untuk aplikasi.
Pertama, aktifkan aplikasi agar dapat membaca dari dan menulis ke dalam Electronic Programming Guide (EPG) sistem, yang datanya mencakup berbagai saluran dan program yang tersedia untuk pengguna. Untuk memungkinkan aplikasi Anda melakukan tindakan ini dan menyinkronkan dengan EPG setelah perangkat dimulai ulang, tambahkan elemen berikut ke manifes aplikasi Anda:
<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 berbagai 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 berasal dari file XMLTV, buat saluran secara terprogram menggunakan class Channel.Builder
.
Untuk setiap saluran, sistem akan memanggil getProgramsForChannel()
saat membutuhkan daftar program yang dapat dilihat selama jangka waktu tertentu pada saluran. Tampilkan daftar objek Program
untuk saluran. Gunakan class XmlTvParser
untuk menampilkan 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 memiliki program dengan jumlah terbatas yang ingin diulang dalam sebuah loop di saluran Anda, saat menyetel informasi tentang program Anda, gunakan metode InternalProviderData.setRepeatable()
dengan nilai yang disetel ke true
.
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 saluran dan data program. Salah satu cara untuk melakukan ini adalah meminta pengguna melakukannya melalui UI dalam aktivitas. Atau, Anda juga dapat membuat aplikasi otomatis melakukannya 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 proses sinkronisasi selesai, jadi Anda harus membuat periode permintaan Anda relatif singkat.
Gunakan metode setUpPeriodicSync()
untuk membuat 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 muatan berlebih tambahan dari requestImmediateSync()
yang memungkinkan Anda menentukan durasi sinkronisasi data saluran dalam satuan milidetik. Metode default menyinkronkan data saluran selama satu jam.
Library Pendamping TIF juga menyediakan metode muatan berlebih tambahan, yaitu setUpPeriodicSync()
, yang memungkinkan Anda menentukan durasi sinkronisasi data saluran, dan seberapa sering sinkronisasi periodik 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 Anda luaskan untuk menangani panggilan saluran dan sesi dari sistem.
Subclass BaseTvInputService
Anda membuat sesi yang akan 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 yang ada pada 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 satuan milidetik. Gunakan antarmuka TvPlayer
untuk mulai memutar program.
Kode media player Anda harus mengimplementasikan TvPlayer
untuk menangani peristiwa pemutaran tertentu. Class TvPlayer
menangani fitur seperti kontrol pergeseran waktu tanpa menambah kompleksitas pada implementasi BaseTvInputService
.
Dalam metode getTvPlayer()
sesi Anda, tampilkan media player 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 perlu menerapkan komponen berikut:
TvInputService
menyediakan ketersediaan input TV yang berdurasi panjang 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, untuk skema rating konten kustomTvInputManager
menyediakan API untuk 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 yang terikat di mana layanan sistem adalah klien yang mengikatnya. Metode siklus proses layanan yang Anda butuhkan untuk implementasi diilustrasikan di gambar 1.
Metode onCreate()
menginisialisasi dan menjalankan HandlerThread
yang menyediakan thread proses yang terpisah dari UI thread untuk menangani tindakan yang berbasis sistem. Dalam contoh berikut, metode onCreate()
menginisialisasi CaptioningManager
dan bersiap untuk menangani tindakan ACTION_BLOCKED_RATINGS_CHANGED
dan ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED
. Kedua tindakan tersebut menjelaskan intent sistem yang dipicu saat pengguna mengubah setelan kontrol orang tua, dan saat ada perubahan pada daftar peringkat 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); }

Gambar 1: Siklus proses TvInputService
Untuk mengetahui informasi selengkapnya mengenai bekerja dengan konten yang diblokir serta menyediakan setelan kontrol orang tua, lihat Mengontrol konten. Untuk melihat lebih banyak tindakan berbasis sistem yang mungkin ingin Anda kelola di dalam layanan input TV, lihat TvInputManager
.
TvInputService
membuat TvInputService.Session
yang mengimplementasikan Handler.Callback
untuk menangani perubahan status pemutar. Dengan onSetSurface()
, TvInputService.Session
menyetel Surface
dengan konten video. Untuk mengetahui informasi selengkapnya tentang bekerja dengan Surface
untuk merender video, lihat Mengintegrasi pemutar dengan surface.
TvInputService.Session
menangani peristiwa onTune()
saat pengguna memilih suatu 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 pilihan trek pada 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 rekaman saluran untuk database sistem. Aplikasi TV yang ada pada sistem akan mengaktifkan aktivitas penyiapan saat tidak dapat menemukan saluran untuk masukan TV.
Aktivitas penyiapan mendeskripsikan saluran yang tersedia di input TV kepada aplikasi TV yang ada pada sistem, seperti yang dijelaskan di pelajaran berikutnya, Membuat dan mengupdate data saluran.