Mengembangkan layanan input TV

Layanan input TV mewakili sumber streaming media, dan memungkinkan Anda menyajikan konten media dalam model TV linear sebagai saluran dan program. Dengan layanan input TV, Anda bisa menyediakan fitur kontrol orang tua, informasi panduan program, dan rating konten. Layanan input TV berfungsi dengan aplikasi TV sistem Android. Aplikasi ini sepenuhnya mengontrol dan menyajikan konten saluran di TV. Aplikasi TV yang ada pada sistem dikembangkan khusus untuk perangkat dan tidak dapat diubah oleh aplikasi pihak ketiga. Untuk informasi selengkapnya tentang Framework Input TV (TIF) arsitektur dan komponennya, lihat Framework Input TV.

Membuat layanan input TV menggunakan Library Pendamping TIF

Library Pendamping TIF adalah kerangka kerja yang menyediakan ekstensi implementasi fitur layanan input TV yang umum. Alat ini dimaksudkan untuk digunakan oleh OEM untuk membuat saluran khusus 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 androidtv-sample-inputs repositori resource. Lihat repositori tersebut untuk mengetahui contoh cara menyertakan library dalam aplikasi.

Mendeklarasikan layanan input TV dalam manifes

Aplikasi Anda harus menyediakan versi yang kompatibel dengan TvInputService layanan yang digunakan sistem untuk mengakses aplikasi Anda. TIF Library Pendamping menyediakan class BaseTvInputService, yang menyediakan implementasi default TvInputService yang dapat Anda sesuaikan. Buat subclass dari BaseTvInputService, dan mendeklarasikan subclass dalam manifes Anda sebagai layanan.

Di dalam deklarasi manifes, tentukan atribut BIND_TV_INPUT untuk mengizinkan untuk 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 Anda, sertakan filter intent yang menentukan TvInputService sebagai tindakan yang akan dilakukan dengan intent. Deklarasikan juga metadata layanan sebagai resource XML yang terpisah. Tujuan 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. Layanan file XML metadata harus menyertakan antarmuka penyiapan yang menjelaskan konfigurasi awal dan pemindaian saluran. File metadata juga harus berisi yang menyatakan apakah pengguna dapat merekam konten atau tidak. Untuk selengkapnya informasi tentang cara mendukung perekaman konten di aplikasi Anda, lihat Mendukung perekaman konten.

File metadata layanan berada 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 buat file XML di res/xml/richtvinputservice.xml, dengan kode 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 digunakan diakses melalui aplikasi TV yang ada di sistem. Anda harus mendaftarkan channel Anda dalam database sistem, dan menyediakan aktivitas penyiapan yang dipanggil saat tidak dapat menemukan saluran untuk aplikasi Anda.

Pertama, aktifkan aplikasi Anda untuk membaca dari dan menulis ke sistem Elektronik Panduan Pemrograman (EPG), yang datanya mencakup saluran dan program yang tersedia kepada pengguna. Agar aplikasi Anda dapat 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 EpgSyncJobService . Kelas abstrak ini memudahkan pembuatan layanan pekerjaan yang membuat dan memperbarui saluran dalam {i>database<i} sistem.

Di subclass Anda, buat dan tampilkan daftar lengkap saluran di getChannels(). Jika saluran Anda berasal dari file XMLTV, menggunakan class XmlTvParser. Jika tidak, buat saluran secara terprogram menggunakan class Channel.Builder.

Untuk setiap saluran, sistem akan memanggil getProgramsForChannel() saat membutuhkan daftar program yang dapat dilihat dalam periode waktu tertentu pada channel. Menampilkan daftar objek Program untuk saluran TV Anda. Gunakan class XmlTvParser untuk mendapatkan program dari XMLTV, atau buat secara terprogram menggunakan Class Program.Builder.

Untuk setiap objek Program, gunakan atribut InternalProviderData untuk menetapkan informasi program seperti jenis video program. Jika Anda hanya memiliki sedikit program yang dapat ingin agar saluran diulang dalam loop, gunakan Metode InternalProviderData.setRepeatable() dengan nilai true saat menyetel 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 melakukan ini adalah meminta pengguna melakukannya melalui UI dalam aktivitas. Aplikasi juga dapat melakukannya secara otomatis saat aktivitas dimulai. Ketika aktivitas penyiapan perlu menyinkronkan saluran dan aplikasi harus memulai layanan pekerjaan:

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 pekerjaan. Pengguna harus menunggu sinkronisasi selesai, jadi Anda harus membuat periode permintaan Anda relatif singkat.

Menggunakan metode setUpPeriodicSync() untuk memiliki layanan tugas menyinkronkan data saluran dan program di latar belakang secara berkala:

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 kelebihan beban tambahan requestImmediateSync() yang memungkinkan Anda menentukan durasi data saluran yang disinkronkan dalam milidetik. Metode {i>default<i} menyinkronkan nilai total data channel.

Library Pendamping TIF juga menyediakan metode kelebihan beban tambahan setUpPeriodicSync() yang memungkinkan Anda menentukan durasi untuk melakukan sinkronisasi, dan seberapa sering sinkronisasi berkala harus terjadi. Tujuan default menyinkronkan 48 jam data saluran setiap 12 jam.

Untuk detail selengkapnya tentang data saluran dan EPG, 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, dibuat oleh aplikasi Anda, untuk menyesuaikan ke saluran yang diminta dan memutar konten. Library Pendamping TIF menyediakan beberapa 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, dan panggil super.sessionCreated() dengan sesi baru Anda. Dalam contoh, 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 di 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 mulai diputar.

Sistem kemudian mendapatkan program yang saat ini dijadwalkan dan memanggil metode onPlayProgram() sesi, yang menentukan program informasi dan waktu mulai dalam milidetik. Gunakan TvPlayer untuk mulai memutar program.

Kode pemutar media 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 pemutar media yang mengimplementasikan TvPlayer. Tujuan Aplikasi contoh Layanan Input TV mengimplementasikan pemutar media yang menggunakan ExoPlayer.

Membuat layanan input TV menggunakan framework input TV

Jika layanan input TV tidak dapat menggunakan Library Pendamping TIF, Anda harus untuk menerapkan komponen berikut:

  • TvInputService menyediakan ketersediaan yang berjalan lama dan di latar belakang untuk input TV
  • TvInputService.Session mempertahankan status input TV dan berkomunikasi dengan aplikasi hosting
  • TvContract menjelaskan saluran dan program yang tersedia untuk TV masukan
  • TvContract.Channels merepresentasikan informasi tentang saluran TV
  • TvContract.Programs mendeskripsikan program TV dengan data seperti program judul dan waktu mulai
  • TvTrackInfo merepresentasikan trek subtitel, audio, atau video
  • TvContentRating mendeskripsikan rating konten, memungkinkan konten kustom skema rating
  • TvInputManager menyediakan API ke aplikasi TV yang ada pada sistem dan mengelola interaksi dengan input TV dan aplikasi

Anda juga perlu melakukan yang berikut ini:

  1. Deklarasikan layanan input TV Anda dalam manifes, sebagai yang dijelaskan dalam Mendeklarasikan layanan input TV Anda dalam manifes.
  2. Buat file metadata layanan.
  3. Buat dan daftarkan informasi saluran dan program Anda.
  4. Buat aktivitas penyiapan Anda.

Menentukan layanan input TV Anda

Untuk layanan Anda, perluas class TvInputService. J Implementasi TvInputService adalah layanan terikat tempat layanan sistem adalah klien yang mengikatnya. Metode siklus proses layanan yang perlu Anda implementasikan diilustrasikan dalam gambar 1.

Metode onCreate() melakukan inisialisasi dan memulai HandlerThread yang menyediakan thread proses yang terpisah dari UI thread untuk menangani tindakan yang didorong oleh sistem. Dalam contoh berikut, onCreate() menginisialisasi CaptioningManager dan bersiap untuk menangani ACTION_BLOCKED_RATINGS_CHANGED dan tindakan ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED. Ini tindakan 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);
}

Gambar 1: Siklus proses TvInputService

Lihat Kontrol konten untuk mengetahui informasi lebih lanjut mengenai cara menangani konten yang diblokir serta memberikan kontrol orang tua. Lihat TvInputManager untuk mengetahui tindakan berbasis sistem lainnya yang yang mungkin ingin ditangani di layanan input TV.

TvInputService membuat TvInputService.Session yang mengimplementasikan Handler.Callback untuk menangani perubahan status pemutar. Dengan onSetSurface(), TvInputService.Session akan menetapkan Surface dengan konten video Anda. Lihat Mengintegrasikan pemutar dengan platform untuk informasi selengkapnya tentang bekerja dengan Surface untuk merender video.

TvInputService.Session menangani onTune() saat pengguna memilih saluran, dan memberi tahu aplikasi TV yang ada pada sistem untuk perubahan konten dan metadata konten. Metode notify() ini dijelaskan dalam Mengontrol Konten dan Menangani pemilihan trek lebih lanjut dalam pelatihan ini.

Mendefinisikan aktivitas penyiapan Anda

Aplikasi TV yang ada pada sistem berjalan dengan aktivitas penyiapan yang Anda tentukan untuk input TV Anda. Tujuan penyiapan diperlukan dan harus menyediakan minimal satu rekaman saluran untuk database sistem. Tujuan aplikasi TV sistem memanggil aktivitas penyiapan saat tidak dapat menemukan saluran untuk input TV.

Aktivitas penyiapan menjelaskan saluran yang disediakan melalui TV ke aplikasi TV yang ada pada sistem input, seperti yang ditunjukkan dalam pelajaran berikutnya, Membuat dan memperbarui data saluran.

Referensi tambahan