Разработать сервис ТВ-ввода

Сервис ввода ТВ представляет собой источник медиапотока и позволяет отображать медиаконтент в линейном формате телевещания в виде каналов и программ. С помощью сервиса ввода ТВ вы можете предоставлять родительский контроль, информацию о программе передач и рейтинги контента. Сервис ввода ТВ работает с системным приложением ТВ Android. Это приложение в конечном итоге управляет и отображает контент каналов на телевизоре. Системное приложение ТВ разработано специально для устройства и не может быть изменено сторонними приложениями. Для получения дополнительной информации об архитектуре TV Input Framework (TIF) и ее компонентах см. TV Input Framework .

Создайте службу ввода для телевизора, используя библиотеку TIF Companion Library.

Библиотека TIF Companion Library — это фреймворк, предоставляющий расширяемые реализации распространенных функций сервисов ввода с телевизора. Она предназначена для использования производителями оборудования (OEM) для создания каналов только для Android 5.0 (уровень API 21) до Android 7.1 (уровень API 25).

Обновите свой проект

Библиотека TIF Companion Library доступна для использования производителями оборудования в устаревших системах в репозитории androidtv-sample-inputs . Пример использования библиотеки в приложении можно найти в этом репозитории.

Укажите тип входного сигнала вашего телевизора в манифесте.

Ваше приложение должно предоставлять службу, совместимую с TvInputService , которую система будет использовать для доступа к вашему приложению. Библиотека TIF Companion Library предоставляет класс BaseTvInputService , который предлагает реализацию TvInputService по умолчанию, которую вы можете настроить. Создайте подкласс BaseTvInputService и объявите этот подкласс в вашем манифесте как службу.

В объявлении манифеста укажите разрешение BIND_TV_INPUT , чтобы разрешить службе подключать телевизионный вход к системе. Системная служба выполняет привязку и имеет разрешение BIND_TV_INPUT . Системное приложение для телевизора отправляет запросы службам телевизионного входа через интерфейс TvInputManager .

В объявлении вашей службы включите фильтр намерений, указывающий TvInputService в качестве действия, которое необходимо выполнить с помощью намерения. Также объявите метаданные службы как отдельный XML-ресурс. Объявление службы, фильтр намерений и объявление метаданных службы показаны в следующем примере:

<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>

Метаданные сервиса следует определить в отдельном XML-файле. XML-файл метаданных сервиса должен включать интерфейс настройки, описывающий начальную конфигурацию телевизионного входа и сканирование каналов. Файл метаданных также должен содержать флаг, указывающий, могут ли пользователи записывать контент. Для получения дополнительной информации о поддержке записи контента в вашем приложении см. раздел «Поддержка записи контента» .

Файл метаданных сервиса находится в каталоге XML-ресурсов вашего приложения и должен совпадать с именем ресурса, объявленного вами в манифесте. Используя записи манифеста из предыдущего примера, вы должны создать XML-файл по адресу res/xml/richtvinputservice.xml со следующим содержимым:

<?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" />

Определите каналы и создайте действие настройки.

Ваша служба ввода телевизионного сигнала должна определять как минимум один канал, к которому пользователи получают доступ через системное ТВ-приложение. Вам следует зарегистрировать свои каналы в системной базе данных и предоставить действие настройки, которое система запускает, когда не может найти канал для вашего приложения.

Во-первых, разрешите вашему приложению читать и записывать данные в электронную программу передач (ЭПГ), которая включает каналы и программы, доступные пользователю. Чтобы ваше приложение могло выполнять эти действия и синхронизироваться с ЭПГ после перезагрузки устройства, добавьте следующие элементы в манифест вашего приложения:

<uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED "/>

Добавьте следующий элемент, чтобы ваше приложение отображалось в Google Play Store как приложение, предоставляющее контентные каналы на Android TV:

<uses-feature
    android:name="android.software.live_tv"
    android:required="true" />

Далее создайте класс, расширяющий класс EpgSyncJobService . Этот абстрактный класс позволяет создать службу заданий, которая создает и обновляет каналы в системной базе данных.

В вашем подклассе создайте и верните полный список каналов в getChannels . Если ваши каналы берутся из XMLTV-файла, используйте класс XmlTvParser . В противном случае сгенерируйте каналы программно с помощью класса Channel.Builder .

Для каждого канала система вызывает getProgramsForChannel , когда ей нужен список программ, которые можно посмотреть в заданный временной интервал на этом канале. Возвращает список объектов Program для канала. Используйте класс XmlTvParser для получения программ из XMLTV-файла или сгенерируйте их программно с помощью класса Program.Builder .

Для каждого объекта Program используйте объект InternalProviderData , чтобы задать информацию о программе, например, тип видео. Если у вас ограниченное количество программ, которые вы хотите, чтобы канал повторял в цикле, используйте метод InternalProviderData.setRepeatable со значением true при задании информации о вашей программе.

После внедрения службы заданий добавьте её в манифест приложения:

<service
    android:name=".sync.SampleJobService"
    android:permission="android.permission.BIND_JOB_SERVICE"
    android:exported="true" />

Наконец, создайте действие настройки. Ваше действие настройки должно предоставлять способ синхронизации данных канала и программы. Один из способов сделать это — позволить пользователю сделать это с помощью пользовательского интерфейса в действии. Вы также можете настроить приложение на автоматическую синхронизацию при запуске действия. Когда действию настройки потребуется синхронизировать информацию о канале и программе, приложение должно запустить службу заданий:

Котлин

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));

Для синхронизации службы заданий используйте метод requestImmediateSync . Пользователю придется дождаться завершения синхронизации, поэтому период ожидания запроса должен быть относительно коротким.

Используйте метод setUpPeriodicSync , чтобы служба заданий периодически синхронизировала данные каналов и программ в фоновом режиме:

Котлин

EpgSyncJobService.setUpPeriodicSync(
        context,
        inputId,
        ComponentName(context, SampleJobService::class.java)
)

Java

EpgSyncJobService.setUpPeriodicSync(context, inputId,
        new ComponentName(context, SampleJobService.class));

Библиотека TIF Companion Library предоставляет дополнительный перегруженный метод requestImmediateSync , позволяющий указать продолжительность синхронизации данных канала в миллисекундах. Метод по умолчанию синхронизирует данные канала за один час.

Библиотека TIF Companion Library также предоставляет дополнительный перегруженный метод setUpPeriodicSync , который позволяет указать продолжительность синхронизации данных канала и частоту периодической синхронизации. Метод по умолчанию синхронизирует 48 часов данных канала каждые 12 часов.

Более подробную информацию о данных каналов и электронной программе передач см. в разделе «Работа с данными каналов» .

Обработка запросов на настройку и воспроизведение медиафайлов.

Когда пользователь выбирает определенный канал, приложение системы ТВ использует созданный вашим приложением объект Session для настройки на запрошенный канал и воспроизведения контента. Библиотека TIF Companion Library предоставляет несколько классов, которые вы можете расширить для обработки вызовов каналов и объектов Session из системы.

Ваш подкласс BaseTvInputService создает сессии, которые обрабатывают запросы на настройку. Переопределите метод onCreateSession , создайте сессию, наследующую от класса BaseTvInputService.Session , и вызовите super.sessionCreated с вашей новой сессией. В следующем примере метод onCreateSession возвращает объект RichTvInputSessionImpl , наследующий BaseTvInputService.Session :

Котлин

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;
}

Когда пользователь использует системное ТВ-приложение для начала просмотра одного из ваших каналов, система вызывает метод onPlayChannel вашей сессии. Переопределите этот метод, если вам необходимо выполнить какую-либо специальную инициализацию канала перед началом воспроизведения программы.

Затем система получает текущую запланированную программу и вызывает метод onPlayProgram вашей сессии, указывая информацию о программе и время начала в миллисекундах. Используйте интерфейс TvPlayer , чтобы начать воспроизведение программы.

В коде вашего медиаплеера следует реализовать интерфейс TvPlayer для обработки определенных событий воспроизведения. Класс TvPlayer обрабатывает такие функции, как управление смещением по времени, не усложняя реализацию BaseTvInputService .

В методе getTvPlayer вашей сессии верните медиаплеер, реализующий интерфейс TvPlayer . В примере приложения TV Input Service реализован медиаплеер, использующий ExoPlayer .

Создайте службу ввода для телевизора, используя фреймворк для ввода ТВ-сигнала.

Если ваша служба ввода телевизионного сигнала не может использовать библиотеку TIF Companion Library, вам необходимо реализовать следующие компоненты:

  • TvInputService обеспечивает длительную и фоновую доступность для телевизионного входа.
  • TvInputService.Session поддерживает состояние входного сигнала телевизора и взаимодействует с приложением, на котором он установлен.
  • TvContract описывает каналы и программы, доступные для телевизионного входа.
  • TvContract.Channels представляет информацию о телеканале.
  • TvContract.Programs описывает телепрограмму, предоставляя такие данные, как название программы и время начала.
  • TvTrackInfo представляет собой аудиодорожку, видеодорожку или дорожку субтитров.
  • TvContentRating описывает рейтинг контента и позволяет создавать собственные схемы рейтинга.
  • TvInputManager предоставляет API для системного приложения TV и управляет взаимодействием с телевизионными входами и приложениями.

Вам также необходимо выполнить следующие действия:

  1. Укажите службу ввода с телевизора в манифесте, как описано в разделе «Укажите службу ввода с телевизора в манифесте» .
  2. Создайте файл метаданных сервиса.
  3. Создайте и зарегистрируйте информацию о своем канале и программе.
  4. Создайте свою программу настройки.

Укажите тип входного сигнала вашего телевизора.

Для вашего сервиса вам необходимо расширить класс TvInputService . Реализация TvInputService представляет собой привязанный сервис , где системным сервисом является клиент, который к нему подключается. Методы жизненного цикла сервиса, которые вам необходимо реализовать, показаны на рисунке 1.

Метод onCreate инициализирует и запускает HandlerThread , который предоставляет отдельный поток обработки, не связанный с потоком пользовательского интерфейса, для обработки действий, инициируемых системой. В следующем примере метод onCreate инициализирует CaptioningManager и подготавливается к обработке действий ACTION_BLOCKED_RATINGS_CHANGED и ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED . Эти действия описывают системные намерения, срабатывающие, когда пользователь изменяет настройки родительского контроля, а также когда изменяется список заблокированных оценок.

Котлин

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);
}

Рисунок 1. Жизненный цикл TvInputService.

См. раздел «Управление контентом» для получения дополнительной информации о работе с заблокированным контентом и предоставлении родительского контроля. См. TvInputManager для получения информации о других системных действиях, которые вы можете захотеть обработать в службе ввода ТВ.

Объект TvInputService создает объект TvInputService.Session , реализующий Handler.Callback для обработки изменений состояния проигрывателя. С помощью onSetSurface объект TvInputService.Session устанавливает Surface с видеоконтентом. Дополнительную информацию о работе с Surface для рендеринга видео см. в разделе «Интеграция проигрывателя с поверхностью» .

Метод TvInputService.Session обрабатывает событие onTune , когда пользователь выбирает канал, и уведомляет системное ТВ-приложение об изменениях в содержимом и метаданных содержимого. Эти методы notify более подробно описаны в разделах «Управление содержимым» и «Обработка выбора трека» данного учебного пособия.

Определите параметры настройки.

Приложение «Система ТВ» работает с действием настройки, которое вы определяете для вашего телевизионного входа. Действие настройки является обязательным и должно содержать как минимум одну запись о канале в системной базе данных. Приложение «Система ТВ» вызывает действие настройки, когда не может найти канал для телевизионного входа.

В процессе настройки приложение для телевизора сообщает системе о каналах, доступных через телевизионный вход, как будет показано в следующем уроке « Создание и обновление данных каналов» .

Дополнительные ссылки

,

Сервис ввода ТВ представляет собой источник медиапотока и позволяет отображать медиаконтент в линейном формате телевещания в виде каналов и программ. С помощью сервиса ввода ТВ вы можете предоставлять родительский контроль, информацию о программе передач и рейтинги контента. Сервис ввода ТВ работает с системным приложением ТВ Android. Это приложение в конечном итоге управляет и отображает контент каналов на телевизоре. Системное приложение ТВ разработано специально для устройства и не может быть изменено сторонними приложениями. Для получения дополнительной информации об архитектуре TV Input Framework (TIF) и ее компонентах см. TV Input Framework .

Создайте службу ввода для телевизора, используя библиотеку TIF Companion Library.

Библиотека TIF Companion Library — это фреймворк, предоставляющий расширяемые реализации распространенных функций сервисов ввода с телевизора. Она предназначена для использования производителями оборудования (OEM) для создания каналов только для Android 5.0 (уровень API 21) до Android 7.1 (уровень API 25).

Обновите свой проект

Библиотека TIF Companion Library доступна для использования производителями оборудования в устаревших системах в репозитории androidtv-sample-inputs . Пример использования библиотеки в приложении можно найти в этом репозитории.

Укажите тип входного сигнала вашего телевизора в манифесте.

Ваше приложение должно предоставлять службу, совместимую с TvInputService , которую система будет использовать для доступа к вашему приложению. Библиотека TIF Companion Library предоставляет класс BaseTvInputService , который предлагает реализацию TvInputService по умолчанию, которую вы можете настроить. Создайте подкласс BaseTvInputService и объявите этот подкласс в вашем манифесте как службу.

В объявлении манифеста укажите разрешение BIND_TV_INPUT , чтобы разрешить службе подключать телевизионный вход к системе. Системная служба выполняет привязку и имеет разрешение BIND_TV_INPUT . Системное приложение для телевизора отправляет запросы службам телевизионного входа через интерфейс TvInputManager .

В объявлении вашей службы включите фильтр намерений, указывающий TvInputService в качестве действия, которое необходимо выполнить с помощью намерения. Также объявите метаданные службы как отдельный XML-ресурс. Объявление службы, фильтр намерений и объявление метаданных службы показаны в следующем примере:

<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>

Метаданные сервиса следует определить в отдельном XML-файле. XML-файл метаданных сервиса должен включать интерфейс настройки, описывающий начальную конфигурацию телевизионного входа и сканирование каналов. Файл метаданных также должен содержать флаг, указывающий, могут ли пользователи записывать контент. Для получения дополнительной информации о поддержке записи контента в вашем приложении см. раздел «Поддержка записи контента» .

Файл метаданных сервиса находится в каталоге XML-ресурсов вашего приложения и должен совпадать с именем ресурса, объявленного вами в манифесте. Используя записи манифеста из предыдущего примера, вы должны создать XML-файл по адресу res/xml/richtvinputservice.xml со следующим содержимым:

<?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" />

Определите каналы и создайте действие настройки.

Ваша служба ввода телевизионного сигнала должна определять как минимум один канал, к которому пользователи получают доступ через системное ТВ-приложение. Вам следует зарегистрировать свои каналы в системной базе данных и предоставить действие настройки, которое система запускает, когда не может найти канал для вашего приложения.

Во-первых, разрешите вашему приложению читать и записывать данные в электронную программу передач (ЭПГ), которая включает каналы и программы, доступные пользователю. Чтобы ваше приложение могло выполнять эти действия и синхронизироваться с ЭПГ после перезагрузки устройства, добавьте следующие элементы в манифест вашего приложения:

<uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED "/>

Добавьте следующий элемент, чтобы ваше приложение отображалось в Google Play Store как приложение, предоставляющее контентные каналы на Android TV:

<uses-feature
    android:name="android.software.live_tv"
    android:required="true" />

Далее создайте класс, расширяющий класс EpgSyncJobService . Этот абстрактный класс позволяет создать службу заданий, которая создает и обновляет каналы в системной базе данных.

В вашем подклассе создайте и верните полный список каналов в getChannels . Если ваши каналы берутся из XMLTV-файла, используйте класс XmlTvParser . В противном случае сгенерируйте каналы программно с помощью класса Channel.Builder .

Для каждого канала система вызывает getProgramsForChannel , когда ей нужен список программ, которые можно посмотреть в заданный временной интервал на этом канале. Возвращает список объектов Program для канала. Используйте класс XmlTvParser для получения программ из XMLTV-файла или сгенерируйте их программно с помощью класса Program.Builder .

Для каждого объекта Program используйте объект InternalProviderData , чтобы задать информацию о программе, например, тип видео. Если у вас ограниченное количество программ, которые вы хотите, чтобы канал повторял в цикле, используйте метод InternalProviderData.setRepeatable со значением true при задании информации о вашей программе.

После внедрения службы заданий добавьте её в манифест приложения:

<service
    android:name=".sync.SampleJobService"
    android:permission="android.permission.BIND_JOB_SERVICE"
    android:exported="true" />

Наконец, создайте действие настройки. Ваше действие настройки должно предоставлять способ синхронизации данных канала и программы. Один из способов сделать это — позволить пользователю сделать это с помощью пользовательского интерфейса в действии. Вы также можете настроить приложение на автоматическую синхронизацию при запуске действия. Когда действию настройки потребуется синхронизировать информацию о канале и программе, приложение должно запустить службу заданий:

Котлин

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));

Для синхронизации службы заданий используйте метод requestImmediateSync . Пользователю придется дождаться завершения синхронизации, поэтому период ожидания запроса должен быть относительно коротким.

Используйте метод setUpPeriodicSync , чтобы служба заданий периодически синхронизировала данные каналов и программ в фоновом режиме:

Котлин

EpgSyncJobService.setUpPeriodicSync(
        context,
        inputId,
        ComponentName(context, SampleJobService::class.java)
)

Java

EpgSyncJobService.setUpPeriodicSync(context, inputId,
        new ComponentName(context, SampleJobService.class));

Библиотека TIF Companion Library предоставляет дополнительный перегруженный метод requestImmediateSync , позволяющий указать продолжительность синхронизации данных канала в миллисекундах. Метод по умолчанию синхронизирует данные канала за один час.

Библиотека TIF Companion Library также предоставляет дополнительный перегруженный метод setUpPeriodicSync , который позволяет указать продолжительность синхронизации данных канала и частоту периодической синхронизации. Метод по умолчанию синхронизирует 48 часов данных канала каждые 12 часов.

Более подробную информацию о данных каналов и электронной программе передач см. в разделе «Работа с данными каналов» .

Обработка запросов на настройку и воспроизведение медиафайлов.

Когда пользователь выбирает определенный канал, приложение системы ТВ использует созданный вашим приложением объект Session для настройки на запрошенный канал и воспроизведения контента. Библиотека TIF Companion Library предоставляет несколько классов, которые вы можете расширить для обработки вызовов каналов и объектов Session из системы.

Ваш подкласс BaseTvInputService создает сессии, которые обрабатывают запросы на настройку. Переопределите метод onCreateSession , создайте сессию, наследующую от класса BaseTvInputService.Session , и вызовите super.sessionCreated с вашей новой сессией. В следующем примере метод onCreateSession возвращает объект RichTvInputSessionImpl , наследующий BaseTvInputService.Session :

Котлин

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;
}

Когда пользователь использует системное ТВ-приложение для начала просмотра одного из ваших каналов, система вызывает метод onPlayChannel вашей сессии. Переопределите этот метод, если вам необходимо выполнить какую-либо специальную инициализацию канала перед началом воспроизведения программы.

Затем система получает текущую запланированную программу и вызывает метод onPlayProgram вашей сессии, указывая информацию о программе и время начала в миллисекундах. Используйте интерфейс TvPlayer , чтобы начать воспроизведение программы.

В коде вашего медиаплеера следует реализовать интерфейс TvPlayer для обработки определенных событий воспроизведения. Класс TvPlayer обрабатывает такие функции, как управление смещением по времени, не усложняя реализацию BaseTvInputService .

В методе getTvPlayer вашей сессии верните медиаплеер, реализующий интерфейс TvPlayer . В примере приложения TV Input Service реализован медиаплеер, использующий ExoPlayer .

Создайте службу ввода для телевизора, используя фреймворк для ввода ТВ-сигнала.

Если ваша служба ввода телевизионного сигнала не может использовать библиотеку TIF Companion Library, вам необходимо реализовать следующие компоненты:

  • TvInputService обеспечивает длительную и фоновую доступность для телевизионного входа.
  • TvInputService.Session поддерживает состояние входного сигнала телевизора и взаимодействует с приложением, на котором он установлен.
  • TvContract описывает каналы и программы, доступные для телевизионного входа.
  • TvContract.Channels представляет информацию о телеканале.
  • TvContract.Programs описывает телепрограмму, предоставляя такие данные, как название программы и время начала.
  • TvTrackInfo представляет собой аудиодорожку, видеодорожку или дорожку субтитров.
  • TvContentRating описывает рейтинг контента и позволяет создавать собственные схемы рейтинга.
  • TvInputManager предоставляет API для системного приложения TV и управляет взаимодействием с телевизионными входами и приложениями.

Вам также необходимо выполнить следующие действия:

  1. Укажите службу ввода с телевизора в манифесте, как описано в разделе «Укажите службу ввода с телевизора в манифесте» .
  2. Создайте файл метаданных сервиса.
  3. Создайте и зарегистрируйте информацию о своем канале и программе.
  4. Создайте свою программу настройки.

Укажите тип входного сигнала вашего телевизора.

Для вашего сервиса вам необходимо расширить класс TvInputService . Реализация TvInputService представляет собой привязанный сервис , где системным сервисом является клиент, который к нему подключается. Методы жизненного цикла сервиса, которые вам необходимо реализовать, показаны на рисунке 1.

Метод onCreate инициализирует и запускает HandlerThread , который предоставляет отдельный поток обработки, не связанный с потоком пользовательского интерфейса, для обработки действий, инициируемых системой. В следующем примере метод onCreate инициализирует CaptioningManager и подготавливается к обработке действий ACTION_BLOCKED_RATINGS_CHANGED и ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED . Эти действия описывают системные намерения, срабатывающие, когда пользователь изменяет настройки родительского контроля, а также когда изменяется список заблокированных оценок.

Котлин

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);
}

Рисунок 1. Жизненный цикл TvInputService.

См. раздел «Управление контентом» для получения дополнительной информации о работе с заблокированным контентом и предоставлении родительского контроля. См. TvInputManager для получения информации о других системных действиях, которые вы можете захотеть обработать в службе ввода ТВ.

Объект TvInputService создает объект TvInputService.Session , реализующий Handler.Callback для обработки изменений состояния проигрывателя. С помощью onSetSurface объект TvInputService.Session устанавливает Surface с видеоконтентом. Дополнительную информацию о работе с Surface для рендеринга видео см. в разделе «Интеграция проигрывателя с поверхностью» .

Метод TvInputService.Session обрабатывает событие onTune , когда пользователь выбирает канал, и уведомляет системное ТВ-приложение об изменениях в содержимом и метаданных содержимого. Эти методы notify более подробно описаны в разделах «Управление содержимым» и «Обработка выбора трека» данного учебного пособия.

Определите параметры настройки.

Приложение «Система ТВ» работает с действием настройки, которое вы определяете для вашего телевизионного входа. Действие настройки является обязательным и должно содержать как минимум одну запись о канале в системной базе данных. Приложение «Система ТВ» вызывает действие настройки, когда не может найти канал для телевизионного входа.

В процессе настройки приложение для телевизора сообщает системе о каналах, доступных через телевизионный вход, как будет показано в следующем уроке « Создание и обновление данных каналов» .

Дополнительные ссылки