Android TV 홈 화면 또는 간단히 홈 화면은 다음과 같은 UI를 제공합니다. 추천 콘텐츠를 채널 및 프로그램의 표로 표시합니다. 각 행이 채널입니다. 채널에는 이 채널에서 볼 수 있는 모든 프로그램의 카드가 포함되어 있습니다.
이 페이지에서는 채널과 프로그램을 홈 화면에 추가하고, 콘텐츠를 업데이트하고, 사용자 작업을 처리하고, 사용자에게 최고의 환경을 제공하는 방법을 보여줍니다. (API에 대해 더 자세히 알아보려면 홈 화면 Codelab I/O 2017 Android TV 세션을 시청하세요.)
참고: 추천 채널은 다음에서만 사용할 수 있습니다. Android 8.0 (API 수준 26) 이상 이를 사용하여 Android 8.0 (API 수준 26) 이상에서 실행되는 앱을 위한 권장사항입니다. 받는사람 이전 버전의 Android에서 실행되는 앱을 위한 권장사항을 제공하고, 를 사용해야 합니다. 추천 행 하세요.
홈 화면 UI
앱은 새 채널을 만들고 프로그램을 채널에 추가, 삭제 및 업데이트하며 채널의 프로그램 순서를 제어할 수 있습니다. 예를 들어, 앱에서 '새로운 기능'이라는 채널을 만들고 새로 공개된 프로그램의 카드를 표시할 수 있습니다.
앱은 채널이 홈 화면에 나타나는 순서를 제어할 수 없습니다. 앱에서 새 채널을 만들면 이 채널이 홈 화면에서 채널 목록의 하단에 추가됩니다. 사용자가 채널을 재정렬하고 숨기고 표시할 수 있습니다.
다음 볼만한 동영상 채널
다음 볼만한 동영상 채널은 홈 화면에 표시되는 두 번째 행으로 앱 행에 표시됩니다. 시스템에서 이 채널을 만들고 유지합니다. 앱에서 프로그램을 다음 볼만한 동영상 채널에 추가했습니다. 자세한 내용은 콘텐츠에 프로그램 추가 다음 볼만한 동영상 채널
앱 채널
앱에서 만드는 채널은 모두 다음 수명 주기를 따릅니다.
- 사용자가 앱에서 채널을 탐색하여 홈 화면에 추가하도록 요청합니다.
- 앱에서 채널을 만들어
TvProvider
에 추가합니다(이 시점에는 이 채널이 표시되지 않음). - 앱이 시스템에 이 채널을 표시하도록 요청합니다.
- 시스템이 사용자에게 새 채널을 승인하도록 요청합니다.
- 새 채널이 홈 화면의 마지막 행에 표시됩니다.
기본 채널
앱은 사용자가 홈 화면에 추가하는 여러 채널을 제공할 수 있습니다. 사용자는 일반적으로 각 채널을 선택하고 승인해야 채널이 홈 화면에 표시됩니다. 모든 앱에는 하나의 기본 채널을 만드는 옵션이 있습니다. 기본 채널은 홈 화면에 자동으로 표시되므로 특별합니다. 사용자는 별도의 설정 없이도 명시적으로 요청합니다
기본 요건
Android TV 홈 화면에서는 Android의 TvProvider
API를 사용하여 앱에서 만드는 채널과 프로그램을 관리합니다.
제공자의 데이터에 액세스하려면 앱의 매니페스트에 다음 권한을 추가하세요.
<uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA" />
TvProvider
지원 라이브러리를 통해 제공자를 더욱 쉽게 사용할 수 있습니다. 이 라이브러리를 build.gradle
파일의 종속 항목에 추가하세요.
Groovy
implementation 'androidx.tvprovider:tvprovider:1.0.0'
Kotlin
implementation("androidx.tvprovider:tvprovider:1.0.0")
채널 및 프로그램 작업을 실행하려면 이러한 지원 라이브러리 가져오기를 프로그램에 포함해야 합니다.
Kotlin
import android.support.media.tv.Channel import android.support.media.tv.TvContractCompat import android.support.media.tv.ChannelLogoUtils import android.support.media.tv.PreviewProgram import android.support.media.tv.WatchNextProgram
자바
import android.support.media.tv.Channel; import android.support.media.tv.TvContractCompat; import android.support.media.tv.ChannelLogoUtils; import android.support.media.tv.PreviewProgram; import android.support.media.tv.WatchNextProgram;
채널
앱에서 만든 첫 번째 채널이 기본 채널이 됩니다. 기본 채널은 홈 화면에 자동으로 표시됩니다. 사용자가 만든 다른 모든 채널은 사용자가 선택하고 승인해야 홈 화면에 표시될 수 있습니다.
채널 만들기
앱이 포그라운드에서 실행되는 경우에만 새로 추가된 채널을 표시하도록 시스템에 요청해야 합니다. 이렇게 하면 사용자가 다른 앱을 실행하는 동안 앱에서 채널 추가 승인을 요청하는 대화상자를 표시하지 않습니다. 백그라운드에서 실행하는 동안 채널을 추가하려고 하면 활동의 onActivityResult()
메서드가 상태 코드 RESULT_CANCELED
를 반환합니다.
채널을 만들려면 다음 단계를 따르세요.
채널 빌더를 만들고 속성을 설정합니다. Note that the 채널 유형은
TYPE_PREVIEW
이어야 합니다. 추가 속성을 필요에 따라 지정할 수 있습니다.Kotlin
val builder = Channel.Builder() // Every channel you create must have the type
TYPE_PREVIEW
builder.setType(TvContractCompat.Channels.TYPE_PREVIEW) .setDisplayName("Channel Name") .setAppLinkIntentUri(uri)자바
Channel.Builder builder = new Channel.Builder(); // Every channel you create must have the type
TYPE_PREVIEW
builder.setType(TvContractCompat.Channels.TYPE_PREVIEW) .setDisplayName("Channel Name") .setAppLinkIntentUri(uri);채널을 제공자에 삽입합니다.
Kotlin
var channelUri = context.contentResolver.insert( TvContractCompat.Channels.CONTENT_URI, builder.build().toContentValues())
자바
Uri channelUri = context.getContentResolver().insert( TvContractCompat.Channels.CONTENT_URI, builder.build().toContentValues());
-
채널에 프로그램을 추가하려면 채널 ID를 저장해야 합니다. 확인할 수 있습니다 반환된 URI에서 채널 ID를 추출합니다.
Kotlin
var channelId = ContentUris.parseId(channelUri)
자바
long channelId = ContentUris.parseId(channelUri);
채널의 로고를 추가해야 합니다.
Uri
또는Bitmap
을 사용하세요. 로고 아이콘은 80dp x 80dp이고 불투명해야 합니다. 이는 프로젝트 원형 마스크:Kotlin
// Choose one or the other storeChannelLogo(context: Context, channelId: Long, logoUri: Uri) // also works if logoUri is a URL storeChannelLogo(context: Context, channelId: Long, logo: Bitmap)
자바
// Choose one or the other storeChannelLogo(Context context, long channelId, Uri logoUri); // also works if logoUri is a URL storeChannelLogo(Context context, long channelId, Bitmap logo);
기본 채널 만들기 (선택사항): 앱에서 첫 번째 채널을 만들 때 채널을 구독하게 되면 기본 채널로 변경하여 홈에 표시합니다. 즉시 화면에 나타납니다. 내가 만든 기타 채널 사용자가 명시적으로 선택됩니다.
Kotlin
TvContractCompat.requestChannelBrowsable(context, channelId)
자바
TvContractCompat.requestChannelBrowsable(context, channelId);
- 앱을 열기 전에 기본 채널이 표시되도록 합니다. 다음과 같은 작업을 할 수 있습니다.
이렇게 하려면
BroadcastReceiver
android.media.tv.action.INITIALIZE_PROGRAMS
작업(홈 화면) 앱이 설치된 후 전송됩니다. 드림 개발 중에 앱을 사이드로드할 때 다음과 같이 이 단계를 테스트할 수 있습니다. adb를 통해 인텐트를 트리거합니다. 여기서 내 앱의 your.package.name/.YourReceiverName<receiver android:name=".RunOnInstallReceiver" android:exported="true"> <intent-filter> <action android:name="android.media.tv.action.INITIALIZE_PROGRAMS" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </receiver>
BroadcastReceiver
:adb shell am broadcast -a android.media.tv.action.INITIALIZE_PROGRAMS -n \ your.package.name/.YourReceiverName
드물지만 앱이 사용자와 동시에 브로드캐스트를 수신할 수 있습니다. 시작할 수 있습니다. 코드로 기본 채널을 추가하려고 시도하지 않는지 확인하세요. 두 번 이상 사용할 수 없습니다.
채널 업데이트
채널 업데이트는 채널을 만드는 것과 매우 유사합니다.
다른 Channel.Builder
를 사용하여 변경해야 하는 속성을 설정하세요.
채널을 업데이트하려면 ContentResolver
를 사용합니다. 채널이 처음에 추가될 때 저장한 채널 ID를 사용하세요.
Kotlin
context.contentResolver.update( TvContractCompat.buildChannelUri(channelId), builder.build().toContentValues(), null, null )
자바
context.getContentResolver().update(TvContractCompat.buildChannelUri(channelId), builder.build().toContentValues(), null, null);
채널의 로고를 업데이트하려면 storeChannelLogo()
를 사용합니다.
채널 삭제
Kotlin
context.contentResolver.delete(TvContractCompat.buildChannelUri(channelId), null, null)
자바
context.getContentResolver().delete(TvContractCompat.buildChannelUri(channelId), null, null);
프로그램
앱 채널에 프로그램 추가
PreviewProgram.Builder
를 만들고 속성을 설정합니다.
Kotlin
val builder = PreviewProgram.Builder() builder.setChannelId(channelId) .setType(TvContractCompat.PreviewPrograms.TYPE_CLIP) .setTitle("Title") .setDescription("Program description") .setPosterArtUri(uri) .setIntentUri(uri) .setInternalProviderId(appProgramId)
자바
PreviewProgram.Builder builder = new PreviewProgram.Builder(); builder.setChannelId(channelId) .setType(TvContractCompat.PreviewPrograms.TYPE_CLIP) .setTitle("Title") .setDescription("Program description") .setPosterArtUri(uri) .setIntentUri(uri) .setInternalProviderId(appProgramId);
프로그램의 유형에 따라 속성을 더 추가하세요. ( 아래 표를 참고하세요.)
프로그램을 제공자에 삽입하세요.
Kotlin
var programUri = context.contentResolver.insert(TvContractCompat.PreviewPrograms.CONTENT_URI, builder.build().toContentValues())
자바
Uri programUri = context.getContentResolver().insert(TvContractCompat.PreviewPrograms.CONTENT_URI, builder.build().toContentValues());
나중에 참조할 수 있도록 프로그램 ID를 검색하세요.
Kotlin
val programId = ContentUris.parseId(programUri)
자바
long programId = ContentUris.parseId(programUri);
다음 볼만한 동영상 채널에 프로그램 추가
다음 볼만한 동영상 채널에 프로그램을 삽입하려면 시청할 동영상에 프로그램 추가를 참고하세요. 다음 채널을 참고하세요.
프로그램 업데이트
프로그램 정보를 변경할 수 있습니다. 예를 들어, 영화의 대여료를 업데이트하거나 사용자가 시청한 프로그램의 양을 표시하는 진행률 표시줄을 업데이트할 수 있습니다.
PreviewProgram.Builder
를 사용하여 변경해야 하는 속성을 설정합니다.
그런 다음 getContentResolver().update
를 호출하여 프로그램을 업데이트합니다. 처음에 프로그램을 추가할 때 저장한 프로그램 ID를 지정하세요.
Kotlin
context.contentResolver.update( TvContractCompat.buildPreviewProgramUri(programId), builder.build().toContentValues(), null, null )
자바
context.getContentResolver().update(TvContractCompat.buildPreviewProgramUri(programId), builder.build().toContentValues(), null, null);
프로그램 삭제
Kotlin
context.contentResolver .delete(TvContractCompat.buildPreviewProgramUri(programId), null, null)
자바
context.getContentResolver().delete(TvContractCompat.buildPreviewProgramUri(programId), null, null);
사용자 작업 처리
앱은 채널을 표시하고 추가할 수 있는 UI를 제공하여 사용자가 콘텐츠를 탐색하는 데 도움을 줄 수 있습니다. 또한 채널이 홈 화면에 표시된 후 앱이 채널과의 상호작용을 처리해야 합니다.
채널 탐색 및 추가
앱은 사용자가 채널을 선택하고 추가할 수 있는 UI 요소를 제공할 수 있습니다(예: 채널을 추가하도록 요청하는 버튼).
사용자가 특정 채널을 요청한 후 다음 코드를 실행하여 채널을 홈 화면 UI에 추가할 수 있는 사용자의 권한을 얻으세요.
Kotlin
val intent = Intent(TvContractCompat.ACTION_REQUEST_CHANNEL_BROWSABLE) intent.putExtra(TvContractCompat.EXTRA_CHANNEL_ID, channelId) try { activity.startActivityForResult(intent, 0) } catch (e: ActivityNotFoundException) { // handle error }
자바
Intent intent = new Intent(TvContractCompat.ACTION_REQUEST_CHANNEL_BROWSABLE); intent.putExtra(TvContractCompat.EXTRA_CHANNEL_ID, channelId); try { activity.startActivityForResult(intent, 0); } catch (ActivityNotFoundException e) { // handle error }
시스템에서 사용자에게 채널을 승인하도록 요청하는 대화상자를 표시합니다.
활동(Activity.RESULT_CANCELED
또는 Activity.RESULT_OK
)의 onActivityResult
메서드에 있는 요청 결과를 처리합니다.
Android TV 홈 화면 이벤트
사용자가 앱에서 게시한 프로그램/채널과 상호작용할 때 홈 화면에서 앱에 인텐트를 보냅니다.
- 사용자가 채널의 로고를 선택하면 홈 화면에서 채널의 APP_LINK_INTENT_URI 속성에 저장된
Uri
를 앱에 보냅니다. 앱에서는 기본 UI 또는 선택한 채널과 관련된 뷰를 시작하기만 하면 됩니다. - 사용자가 프로그램을 선택하면 홈 화면에서 프로그램의 INTENT_URI 속성에 저장된
Uri
를 앱에 보냅니다. 앱에서는 선택한 콘텐츠를 재생하기만 하면 됩니다. - 사용자는 프로그램에 더 이상 관심이 없으며 이 프로그램을 홈 화면의 UI에서 삭제하고 싶다고 표시할 수 있습니다. 시스템이 프로그램을 UI에서 삭제하고 프로그램을 소유하는 앱에 인텐트(android.media.tv.ACTION_PREVIEW_PROGRAM_BROWSABLE_DISABLED 또는 android.media.tv.ACTION_WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED)를 프로그램의 ID와 함께 보냅니다. 앱이 프로그램을 제공자에서 삭제해야 하며 다시 삽입해서는 안 됩니다.
홈 화면에서 사용자 상호작용을 위해 보내는 모든 Uris
에 관한 인텐트 필터를 만들어야 합니다. 예를 들면 다음과 같습니다.
<receiver
android:name=".WatchNextProgramRemoved"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.media.tv.ACTION_WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED" />
</intent-filter>
</receiver>
권장사항
- 대부분 TV 앱을 사용하려면 사용자가 로그인해야 합니다. 이 경우
BroadcastReceiver
android.media.tv.action.INITIALIZE_PROGRAMS
을(를) 듣는 동안 채널 콘텐츠를 볼 수 없습니다.예를 들어, 앱이 처음에 현재 인기 있는 콘텐츠를 표시할 수 있습니다. 사용자가 로그인한 후 맞춤 콘텐츠를 표시할 수 있습니다 이는 앱이 업셀링할 수 있는 좋은 기회입니다. 사용자에게 액세스 권한을 부여할 수 있습니다. - 앱이 포그라운드에 있지 않고 채널이나
프로그램에서
JobScheduler
를 사용하여 작업을 예약합니다 (다음 참고). JobScheduler 및 JobService). - 앱이 오작동하는 경우 시스템에서 앱의 제공자 권한을 취소할 수 있습니다. (예: 제공업체에 계속 데이터 스팸 발송) 반드시 처리하려는 try-catch 절로 제공자에 액세스하는 코드를 래핑합니다. 보안 예외가 적용됩니다.
프로그램 및 채널을 업데이트하기 전에 제공자에 원하는 데이터를 쿼리합니다. 데이터를 업데이트하고 조정해야 합니다. 예를 들어 모든 포드의 상태를 사용자가 UI에서 삭제하려는 프로그램 백그라운드 작업을 사용하여 기존 채널에 대한 승인을 요청할 수 있습니다 다음 경우에 이 작업을 실행할 수 있습니다. 앱이 데이터를 업데이트해야 할 때마다 시작됩니다.
Kotlin
context.contentResolver .query( TvContractCompat.buildChannelUri(channelId), null, null, null, null).use({ cursor-> if (cursor != null and cursor.moveToNext()) { val channel = Channel.fromCursor(cursor) if (channel.isBrowsable()) { //update channel's programs } } })
자바
try (Cursor cursor = context.getContentResolver() .query( TvContractCompat.buildChannelUri(channelId), null, null, null, null)) { if (cursor != null && cursor.moveToNext()) { Channel channel = Channel.fromCursor(cursor); if (channel.isBrowsable()) { //update channel's programs } } }
모든 이미지(로고, 아이콘, 콘텐츠 이미지)에 고유한 Uri를 사용하세요. 이미지를 업데이트하는 경우 다른 Uri를 사용해야 합니다. 모든 이미지는 캐시됩니다. 이미지를 변경할 때 Uri를 변경하지 않으면 이전 이미지가 계속 표시됩니다.
WHERE 절은 허용되지 않으며 WHERE 절을 사용하여 제공자를 호출하면 보안 예외가 발생합니다.
속성
이 섹션에서는 채널 및 프로그램 속성을 별도로 설명합니다.
채널 속성
모든 채널에 다음 속성을 지정해야 합니다.
속성 | 메모 |
---|---|
TYPE | TYPE_PREVIEW 로 설정합니다. |
DISPLAY_NAME | 채널의 이름으로 설정합니다. |
APP_LINK_INTENT_URI | 사용자가 채널의 로고를 선택하면 시스템에서 채널과 관련된 콘텐츠를 제공하는 활동을 시작하기 위해 인텐트를 보냅니다. 이 속성을 해당하는 활동의 인텐트 필터에서 사용된 Uri로 설정하세요. |
또한 채널에는 내부 앱 사용을 위해 예약된 여섯 개의 필드가 있습니다. 이러한 필드는 앱이 채널을 내부 데이터 구조에 매핑할 때 도움이 될 수 있는 키 또는 다른 값을 저장하는 데 사용될 수 있습니다.
- INTERNAL_PROVIDER_ID
- INTERNAL_PROVIDER_DATA
- INTERNAL_PROVIDER_FLAG1
- INTERNAL_PROVIDER_FLAG2
- INTERNAL_PROVIDER_FLAG3
- INTERNAL_PROVIDER_FLAG4
프로그램 속성
각 프로그램 유형의 속성은 개별 페이지를 참조하세요.
샘플 코드
홈 화면과 상호작용하고 채널 및 프로그램을 Android TV 홈 화면에 추가하는 앱을 빌드하는 방법을 자세히 알아보려면 홈 화면 Codelab을 참조하세요.