Android Studio V3.12环境下TV开发教程(十二)帮助用户在电视上找到您的内容

Android Studio V3.12环境下TV开发教程

(转自Android官网https://developer.android.com/training/tv/start)

文章源自:光谷佳武 https://blog.csdn.net/jiawuhan/article/details/80647529


帮助用户在电视上找到您的内容

电视设备提供了许多娱乐选项,其中数以千计的应用和相关内容服务的选择。 同时,大多数用户更喜欢使用输入数量最少的电视机。 有了这么多的选择,你的应用程序应该为用户提供快速和简单的路径来发现和享受你的内容。

Android框架可以帮助您为用户提供大量路径来发现您的内容,包括主屏幕上的推荐内容以及在您的应用内容目录中搜索。

本课程向您展示如何通过推荐和应用内搜索帮助用户发现您的应用内容。

主题

推荐电视内容
了解如何通过在电视设备的主屏幕上显示内容来为用户推荐内容。
让电视应用程序可搜索
了解如何通过Android TV主屏幕搜索您的内容。
在电视应用内搜索
了解如何使用内置的电视用户界面在您的应用内进行搜索。


推荐电视内容

Android TV主屏幕根据Android的运行版本显示两种不同的推荐方式:

  • 在Android 8.0(API级别26)及更高版本中,应用可以在出现在单独行上的一个或多个频道中显示推荐。 总是出现一个频道(默认频道)。 用户可以发现并添加其他频道到他们的主屏幕。 了解如何在主屏幕上创建推荐频道 
  • 在Android 8.0之前,Android TV会在始终显示在屏幕上的单个建议行中显示所有建议。 了解如何在主屏幕上创建推荐行 

确保兼容性

为了能够在所有版本的Android TV上显示建议,您的应用应该同时实施推荐API。 测试当前的系统API级别并使用适当的API来构建推荐行或通道

if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // Use the home screen recommendation channels API } else { // Use the recommendations row API } 

如果您的应用程序是使用API​​级别25或更低版本编译的,则它仍可以在26级的Android TV上运行。旧的建议行为是向前兼容的,但受到限制:

  • 推荐行将自动转换并在主屏幕上显示为新频道。
  • 已转换频道上的节目响应来自推荐服务的更新,但用户无法使用电视的用户界面来操作频道上的节目(添加/删除节目,将节目复制到观看下一频道)。
  • 如果您将应用更新为API级别26,则转换后的频道仍会出现在运行API 26的电视上。当您的应用第一次显示使用新API创建的频道时,电视会从屏幕中删除已转换的频道。 如果应用程序创建默认频道 ,或者稍后用户选择并添加由您的应用创建的任何其他频道,则会立即发生。
注意: 这种向前兼容的行为是暂时的,它将在未来某个时候被删除。   为了确保兼容性,最佳实践是实现两个API,如上所述。

主屏幕上的频道

Android TV主屏幕或简单的主屏幕提供了一个UI,可将推荐内容显示为频道节目表。 每一行都是一个通道。 一个频道包含该频道上每个可用节目的卡片:

电视主屏幕

本文档演示了如何将频道和程序添加到主屏幕,更新内容,处理用户操作并为用户提供最佳体验。 (如果您想深入了解API,请尝试主屏幕codelab并观看I / O 2017 Android TV会话 。)

注意:推荐渠道仅适用于Android 8.0(API级别26)及更高版本。 您必须使用它们来为在Android 8.0(API级别26)和更高版本中运行的应用提供建议。 要为在早期版本的Android上运行的应用提供建议,您的应用必须改用建议行 

主屏幕UI

应用可以创建新频道,添加,删除和更新频道中的节目,并控制频道中节目的顺序。 例如,一个应用程序可以创建一个名为“新功能”的频道,并为新近可用的节目显示卡片。

应用程序无法控制频道在主屏幕中的显示顺序。 当您的应用创建新频道时,主屏幕会将其添加到频道列表的底部。 用户可以重新排序,隐藏和显示频道。

观看下一个频道

Watch Next频道是应用程序行之后出现在主屏幕中的第二行。 系统创建并维护此频道。 您的应用可以将节目添加到Watch Next频道:用户标记为有趣的节目,停止在中间观看,或者与用户正在观看的内容有关的节目(如下一集节目中的下一集或下一季节目)。

Watch Next频道有一些限制:您的应用无法移动,移除或隐藏Watch Next频道的行。

注意: 在主屏幕上,“观看下一个”频道的标签为“播放下一个”。   但是,用于管理Watch Next频道的Android类是WatchNextProgramWatchNextPrograms    他们有方法和常数词干“watchnext”。

应用频道

您的应用创建的所有渠道都遵循此生命周期:

  1. 用户在您的应用中发现频道并请求将其添加到主屏幕。
  2. 应用程序创建通道并将其添加到TvProvider (此时通道不可见)。
  3. 应用程序要求系统显示频道。
  4. 系统要求用户批准新频道。
  5. 新频道出现在主屏幕的最后一行。

默认频道

您的应用可以提供任意数量的频道供用户添加到主屏幕。 用户通常必须在每个频道出现在主屏幕之前选择并批准。 每个应用程序都可以创建一个默认频道。 默认频道是特殊的,因为它自动出现在主屏幕中; 用户不必明确地请求它。

先决条件

Android TV主屏幕使用Android的TvProvider API来管理您的应用创建的频道和节目。 要访问提供者的数据,请将以下权限添加到应用的清单中:

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

TvProvider支持库使得使用提供者更容易。 将它添加到build.gradle文件中的依赖关系中:

 compile 'com.android.support:support-tv-provider:27.0.0' 

要使用频道和节目,请确保在您的节目中包含这些支持库导入:

 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 

要创建频道,请按以下步骤操作:

  1. 创建渠道构建器并设置其属性:
     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); 

    通道类型必须是TYPE_PREVIEW  根据需要添加更多属性 

  2. 将频道插入提供者:
     Uri channelUri = context.getContentResolver().insert( TvContractCompat.Channels.CONTENT_URI, builder.build().toContentValues()); 

    您需要保存频道ID以便稍后将节目添加到频道。 从返回的URI中提取通道ID:

     long channelId = ContentUris.parseId(channelUri); 
  3. 您必须为您的频道添加徽标。 使用UriBitmap 
     // 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); 

    标志图标应该是80dp x 80dp,并且它必须是不透明的。 它显示在一个圆形面具下:

    电视主屏幕图标掩码

  4. 创建默认频道(可选):

    当您的应用程序创建其第一个频道时,您可以将其设为默认频道,以便它立即显示在主屏幕中,而无需用户执行任何操作:

     TvContractCompat.requestChannelBrowsable(context, channelId); 

    您创建的任何其他频道在用户明确选择它们之前都不可见。

更新频道

更新频道与创建频道非常相似。

使用另一个Channel.Builder来设置需要更改的属性。

使用ContentResolver更新频道。 使用频道最初添加时保存的频道ID:

 context.getContentResolver().update(TvContractCompat.buildChannelUri(channelId), builder.build().toContentValues(), null, null); 

要更新频道徽标,请使用storeChannelLogo() 

删除频道

 context.getContentResolver().delete(TvContractCompat.buildChannelUri(channelId), null, null); 
注意: 您不应该删除默认频道。   如果这样做,用户必须再次选择它并要求将其添加到主屏幕。   它不能自动重新出现。   当它被添加回来时,它会出现在主屏幕的底部,就像任何其他新添加的频道一样。

程式

将程序添加到应用程序频道

创建一个PreviewProgram.Builder并设置其属性:

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

根据程序的类型添加更多属性。 (要查看每种类型程序的可用属性,请参阅下 。)

将程序插入提供者:

 Uri programUri = context.getContentResolver().insert(TvContractCompat.PreviewPrograms.CONTENT_URI, builder.build().toContentValues()); 

检索程序ID供以后参考:

 long programId = ContentUris.parseId(programUri); 

将节目添加到Watch Next频道

将节目插入Watch Next频道与将节目插入您自己的频道相同。

注意: 用户可以随时手动将内容添加到Watch Next频道。   但是,您的应用程序应限制其对传统电视节目和电影的程序添加。 避免将剪辑和其他简短内容添加到Watch Next频道。

有四种类型的程序; 选择适当的类型:

类型 笔记
WATCH_NEXT_TYPE_CONTINUE 用户在观看内容时停下来。
WATCH_NEXT_TYPE_NEXT 用户正在观看的系列中的下一个可用节目是可用的。 例如,如果用户正在观看一系列的第3集,则该应用可以建议他们接下来观看第4集。
WATCH_NEXT_TYPE_NEW 明确遵循用户正在观看的新内容现在可用。 例如,用户正在观看一系列的第5集,而第6集可用于观看。
WATCH_NEXT_TYPE_WATCHLIST 当用户保存程序时,由系统或应用程序插入。

使用WatchNextProgram.Builder 

 WatchNextProgram.Builder builder = new WatchNextProgram.Builder(); builder.setType(TvContractCompat.WatchNextPrograms.TYPE_CLIP)    .setWatchNextType(TvContractCompat.WatchNextPrograms.WATCH_NEXT_TYPE_CONTINUE)    .setLastEngagementTimeUtcMillis(time)    .setTitle("Title")    .setDescription("Program description")    .setPosterArtUri(uri)    .setIntentUri(uri)    .setInternalProviderId(appProgramId); Uri watchNextProgramUri = context.getContentResolver() .insert(TvContractCompat.WatchNextPrograms.CONTENT_URI, builder.build().toContentValues()); 

使用TvContractCompat.buildWatchNextProgramUri(long watchNextProgramId)创建您需要更新Watch Next程序的Uri 

当用户将节目添加到Watch Next频道时,系统将该节目复制到该行。 它发送意图TvContractCompat.ACTION_PREVIEW_PROGRAM_ADDED_TO_WATCH_NEXT来通知应用程序已添加该程序。 意图包括两个附加功能:复制的节目ID和在Watch Next频道中为节目创建的节目ID。

更新程序

您可以更改程序的信息。 例如,您可能想要更新电影的租赁价格,或者更新显示用户观看过多少节目的进度条。

使用PreviewProgram.Builder设置需要更改的属性,然后调用getContentResolver().update更新程序。 指定程序最初添加时保存的程序ID:

 context.getContentResolver().update(TvContractCompat.buildPreviewProgramUri(programId), builder.build().toContentValues(), null, null); 

删除程序

 context.getContentResolver().delete(TvContractCompat.buildPreviewProgramUri(programId), null, null); 

处理用户操作

您的应用可以通过提供用户界面来显示和添加频道,帮助用户发现内容。 您的应用在出现在主屏幕后还应处理与您的频道的互动。

发现和增加渠道

您的应用可以提供一个UI元素,让用户选择并添加其频道(例如,要求添加频道的按钮)。 在用户请求特定频道后,执行此代码以获得用户将其添加到主屏幕UI的权限:

 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 } 

系统显示一个对话框,要求用户批准频道。 在您的活动的onActivityResult方法中处理请求的结果( Activity.RESULT_CANCELEDActivity.RESULT_OK )。

Android TV主屏幕事件

当用户与应用程序发布的程序/频道进行交互时,主屏幕将意图发送到应用程序:

  • 当用户选择频道的标志时,主屏幕会将存储在频道的APP_LINK_INTENT_URI属性中的Uri发送到应用程序。 该应用程序应该启动其主UI或与选定频道相关的视图。
  • 当用户选择程序时,主屏幕将存储在程序的INTENT_URI属性中的Uri发送到应用程序。 该应用应播放选定的内容。
  • 用户可以指出他们不再对某个程序感兴趣,并希望将其从主屏幕的用户界面中删除。 系统从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> 

最佳实践

  • 您的应用应该尽快插入默认频道并向用户显示内容。 你可以通过添加一个BroadcastReceiver来实现这一点,它侦听系统在安装应用程序之后发送的android.media.tv.action.INITIALIZE_PROGRAMS “唤醒”意图。 在极少数情况下,您的应用可能会在用户启动它的同时收到“唤醒”广播。 您的代码不应该尝试多次添加默认频道。
  • 许多电视应用程序都要求用户登录。 在这种情况下,您可以添加侦听Intent.ACTION_BOOT_COMPLETEDBroadcastReceiver ,然后为已验证的用户建议备用频道内容。 例如,您的应用最初可以显示最佳内容或当前流行的内容。 用户登录后,它可以显示个性化内容。 这是应用在登录之前向用户推销用户的绝好机会。 leanback-homescreen-channels示例应用程序显示了在系统引导时如何加载频道。
  • 当您的应用程序不在前台并且需要更新频道或程序时,请使用JobScheduler安排工作(请参阅: JobSchedulerJobService )。
  • 如果您的应用程序行为异常(例如:持续向数据提供者发送垃圾邮件),系统可以撤销应用程序的提供程序权限。确保使用try-catch子句来处理访问提供程序的代码以处理安全异常。
  • 在更新程序和渠道之前,请向供应商查询您需要更新和协调数据的数据。 例如,不需要更新用户想要从UI中删除的程序。 在查询现有数据并请求批准您的渠道后,使用后台作业插入/更新您的数据到供应商。 您可以在应用程序启动时以及应用程序需要更新其数据时运行此作业。

      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 } } } 
  • 为所有图像(徽标,图标,内容图像)使用独特的Uris。 更新图像时一定要使用不同的Uri。 所有图像都被缓存。 如果在更改图像时不更改Uri,则旧图像将继续显示。

  • 请记住,不允许使用WHERE子句,并且使用WHERE子句调用提供程序将引发安全异常。

属性

本节分别介绍通道和程序属性。

渠道属性

您必须为每个通道指定这些属性:

属性 笔记
类型 设置为TYPE_PREVIEW 
显示名称 设置为频道的名称。
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主屏幕,请参阅我们的主屏幕codelabgithub示例 


猜你喜欢

转载自blog.csdn.net/jiawuhan/article/details/80647529