TV 입력 서비스 개발

TV 입력 서비스는 미디어 스트림 소스를 나타내며, 이를 통해 미디어 콘텐츠를 채널과 프로그램 같은 선형 방송 TV 패션입니다. TV 입력 서비스를 사용하면 자녀 보호 기능, 프로그램 가이드 정보, 콘텐츠 등급 등이 있습니다. TV 입력 서비스가 작동합니다. Android 시스템 TV 앱과도 같습니다. 이 앱은 궁극적으로 채널 콘텐츠를 제어하고 제공합니다. TV에서 시스템 TV 앱은 기기 전용으로 개발되었으며 변경할 수 없습니다. 할 수 있습니다. TV 입력 프레임워크 (TIF) 자세히 알아보기 자세한 내용은 <ph type="x-smartling-placeholder"></ph> TV 입력 프레임워크를 참조하세요.

TIF 컴패니언 라이브러리를 사용하여 TV 입력 서비스 만들기

TIF 컴패니언 라이브러리는 확장 가능한 일반적인 TV 입력 서비스 기능을 구현한 것입니다. OEM에서 사용하여 채널만 지원합니다.

프로젝트 업데이트

TIF 호환 라이브러리는 androidtv-sample-inputs 저장소 앱에 라이브러리를 포함하는 방법의 예는 이 저장소를 참고하세요.

매니페스트에서 TV 입력 서비스 선언

앱은 TvInputService 호환 시스템에서 앱에 액세스하는 데 사용하는 서비스입니다. TIF 컴패니언 라이브러리는 BaseTvInputService 클래스를 제공하며 TvInputService의 기본 구현을 제공합니다. 맞춤설정할 수 있습니다. BaseTvInputService의 서브클래스를 만듭니다. 매니페스트의 서브클래스를 서비스로 선언하세요.

매니페스트 선언 내에서 BIND_TV_INPUT 권한을 사용하여 TV 입력을 시스템에 연결합니다. 시스템 서비스 가 바인딩을 수행하고 BIND_TV_INPUT 권한 시스템 TV 앱이 TV 입력 서비스에 요청을 전송 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 파일에는 TV 입력의 초기 구성 및 채널 스캔을 수행합니다. 메타데이터 파일에는 사용자가 콘텐츠를 녹화할 수 있는지 여부를 나타내는 플래그입니다. 자세한 내용은 앱에서 콘텐츠 녹화를 지원하는 방법에 관한 자세한 내용은 콘텐츠 녹화 지원:

서비스 메타데이터 파일은 XML 리소스 디렉터리에 있습니다. 하고 합니다. 이전 예의 매니페스트 항목을 사용하면 res/xml/richtvinputservice.xml에서 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" />

채널 정의 및 설정 활동 만들기

TV 입력 서비스는 사용자가 시청할 수 있는 채널을 하나 이상 정의해야 합니다. 시스템 TV 앱을 통해 액세스할 수 있습니다. 채널을 등록해야 합니다. 구성되고 시스템이 실행하는 설정 활동을 앱의 채널을 찾을 수 없을 때 호출됩니다.

먼저 앱이 시스템에서 읽고 쓸 수 있도록 사용 설정합니다. 전자 기기 프로그램 가이드 (EPG) - 이용 가능한 채널과 프로그램을 포함하는 데이터 제공 표시됩니다. 앱에서 이러한 작업을 실행할 수 있도록 하려면 기기를 다시 시작한 후 EPG의 경우 앱 매니페스트에 다음 요소를 추가합니다.

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

앱이 Android TV에서 콘텐츠 채널을 제공하는 앱으로서의 Google Play 스토어:

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

마지막으로 설정 활동을 만드세요. 설정 활동을 통해 채널과 프로그램 데이터를 동기화합니다. 이를 위한 한 가지 방법은 사용자가 할 수 있습니다. 앱에서 자동 실행되도록 할 수도 있습니다. 활동을 시작할 때 설정 활동에서 채널과 앱이 작업 서비스를 시작해야 합니다.

Kotlin

val inputId = getActivity().intent.getStringExtra(TvInputInfo.EXTRA_INPUT_ID)
EpgSyncJobService.cancelAllSyncRequests(getActivity())
EpgSyncJobService.requestImmediateSync(
        getActivity(),
        inputId,
        ComponentName(getActivity(), SampleJobService::class.java)
)

자바

String inputId = getActivity().getIntent().getStringExtra(TvInputInfo.EXTRA_INPUT_ID);
EpgSyncJobService.cancelAllSyncRequests(getActivity());
EpgSyncJobService.requestImmediateSync(getActivity(), inputId,
        new ComponentName(getActivity(), SampleJobService.class));

requestImmediateSync() 메서드를 사용하여 동기화 작업 서비스에 액세스할 수 있습니다 사용자는 동기화가 완료될 때까지 기다려야 하므로 요청 기간을 비교적 짧게 유지하세요

setUpPeriodicSync() 메서드를 사용하여 작업 서비스 사용 백그라운드에서 채널과 프로그램 데이터를 주기적으로 동기화합니다.

Kotlin

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

자바

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

TIF 컴패니언 라이브러리는 requestImmediateSync()를 사용하면 밀리초 단위로 동기화해야 합니다. 기본 메서드는 1시간 동안의 가치가 있습니다.

또한 TIF 컴패니언 라이브러리는 setUpPeriodicSync()를 사용하면 동기화할 채널 데이터 및 주기적 동기화가 수행되어야 하는 빈도를 지정합니다. 이 기본 방법은 12시간마다 48시간 분량의 채널 데이터를 동기화합니다.

채널 데이터 및 EPG에 대한 자세한 내용은 채널 데이터 사용

미세 조정 요청 및 미디어 재생 처리

사용자가 특정 채널을 선택하면 시스템 TV 앱에서 앱에서 생성된 Session: 요청된 채널에 맞춥니다. 콘텐츠를 재생할 수 있습니다. TIF 컴패니언 라이브러리는 TIF 컴패니언 라이브러리를 통해 클래스가 있습니다.

BaseTvInputService 서브클래스는 조정 요청을 수행합니다 이 onCreateSession() 메서드에서 확장하려면 다음에서 확장된 세션을 만듭니다. BaseTvInputService.Session 클래스를 호출하고 새 세션으로 super.sessionCreated(). 다음에서 예를 들어 onCreateSession()는 확장되는 RichTvInputSessionImpl 객체 BaseTvInputService.Session:

Kotlin

override fun onCreateSession(inputId: String): Session =
        RichTvInputSessionImpl(this, inputId).apply {
            setOverlayViewEnabled(true)
        }

자바

@Override
public final Session onCreateSession(String inputId) {
    RichTvInputSessionImpl session = new RichTvInputSessionImpl(this, inputId);
    session.setOverlayViewEnabled(true);
    return session;
}

사용자가 시스템 TV 앱을 사용하여 채널 중 하나를 보기 시작하면 시스템이 세션의 onPlayChannel() 메서드를 호출합니다. 재정의 이 메서드를 호출하기 전에 특수 채널 초기화를 수행해야 하는 경우 프로그램 재생이 시작됩니다.

그러면 시스템에서 현재 예정된 프로그램을 가져와 세션의 onPlayProgram() 메서드: 프로그램 지정 시작 시간(밀리초 단위)을 지정합니다. 사용 TvPlayer 인터페이스를 사용하여 프로그램 재생을 시작할 수 있습니다.

미디어 플레이어 코드는 TvPlayer를 구현하여 지정할 수 있습니다. TvPlayer 클래스는 특성을 처리합니다. 타임 시프팅 제어 같은 기능을 수행할 수 있습니다. BaseTvInputService 구현.

세션의 getTvPlayer() 메서드에서 다음을 반환합니다. TvPlayer를 구현하는 미디어 플레이어입니다. 이 <ph type="x-smartling-placeholder"></ph> TV 입력 서비스 샘플 앱은 다음을 사용하는 미디어 플레이어를 구현합니다. ExoPlayer

TV 입력 프레임워크를 사용하여 TV 입력 서비스 만들기

TV 입력 서비스에서 TIF 컴패니언 라이브러리를 사용할 수 없는 경우 다음이 필요합니다. 다음 구성요소를 구현합니다.

  • TvInputService는 장기 실행 및 백그라운드 가용성을 제공합니다. TV 입력
  • TvInputService.Session는 TV 입력 상태를 유지하고 호스팅 앱
  • TvContract - TV에서 사용할 수 있는 채널과 프로그램을 설명합니다. 입력
  • TvContract.Channels - TV 채널에 관한 정보를 나타냅니다.
  • TvContract.Programs - 프로그램과 같은 데이터를 사용하여 TV 프로그램을 설명합니다. 제목 및 시작 시간
  • TvTrackInfo - 오디오, 동영상 또는 자막 트랙을 나타냅니다.
  • TvContentRating는 콘텐츠 등급을 설명하고 맞춤 콘텐츠를 허용합니다. 평가 체계
  • TvInputManager는 시스템 TV 앱에 API를 제공하고 TV 입력 및 앱과의 상호작용을 통해

또한 다음을 실행해야 합니다.

  1. 매니페스트에서 TV 입력 서비스를 다음과 같이 선언합니다. 매니페스트를 참조하세요.
  2. 서비스 메타데이터 파일을 만듭니다.
  3. 채널과 프로그램 정보를 만들고 등록합니다.
  4. 설정 활동을 만듭니다.

TV 입력 서비스 정의

서비스의 TvInputService 클래스를 확장합니다. 가 TvInputService 구현은 바인드된 서비스: 시스템 서비스가 클라이언트입니다. 서비스 수명 주기 메서드 그림 1에 나와 있습니다.

onCreate() 메서드는 HandlerThread는 UI 스레드와 분리된 프로세스 스레드를 제공하여 시스템 기반 작업을 처리합니다 다음 예에서 onCreate()는 메서드는 CaptioningManager를 초기화하고 ACTION_BLOCKED_RATINGS_CHANGEDACTION_PARENTAL_CONTROLS_ENABLED_CHANGED 작업 이러한 작업은 사용자가 자녀 보호 기능 설정을 변경했을 때와 차단된 평점 목록에 변경사항이 있는지 확인합니다.

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

자바

@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 페이지를 참고하세요. TV 입력 서비스에서 처리하고 싶을 수 있습니다.

TvInputServiceHandler.Callback를 구현하는 TvInputService.Session 플레이어 상태 변경을 처리할 수 있습니다. 다음으로 바꿉니다. onSetSurface(), TvInputService.SessionSurface 동영상 콘텐츠입니다. 플레이어를 노출 영역과 통합을 참고하세요. Surface를 사용하여 동영상을 렌더링하는 방법에 대한 자세한 내용을 참조하세요.

TvInputService.SessiononTune() 이벤트를 발생시키고, 시스템 TV 앱에 콘텐츠 및 콘텐츠의 변경을 알립니다. 콘텐츠 메타데이터 이러한 notify() 메서드는 <ph type="x-smartling-placeholder"></ph> 콘텐츠 제어트랙 선택 처리 더 자세히 살펴보겠습니다

설정 활동 정의

시스템 TV 앱에서는 TV 입력에 정의된 설정 활동을 사용합니다. 이 설정 활동은 필수이며 시스템 데이터베이스에 대한 하나 이상의 채널 레코드를 제공해야 합니다. 이 시스템 TV 앱은 TV 입력을 위한 채널을 찾을 수 없을 때 설정 활동을 호출합니다.

설정 활동은 TV를 통해 사용할 수 있게 한 채널을 시스템 TV 앱에 설명합니다. 다음 강의에 설명된 대로 채널 데이터를 업데이트합니다.

추가 자료