android:tv直播_Android TV:吸引应用的最佳做法

android:tv直播

Creating a great Android TV app is about getting the basics right, customizing the Leanback library to get the look and feel you want, integrating with Android TV features so people can discover and control your content, and, of course, delivering great content. The latter I’ll leave you to figure out, but for the first 3, this post will get you heading in the right direction. To kick off I want to briefly look at how technology is changing the home and living room.

创建一个出色的Android TV应用程序涉及正确的基础知识,自定义Leanback库以获取所需的外观和感觉,与Android TV功能集成以便人们可以发现和控制您的内容,当然还可以提供出色的内容。 后者我会让你弄清楚,但对于前三个,这篇文章将使您朝正确的方向前进。 首先,我想简要介绍一下技术如何改变家庭和客厅。

现代家庭和客厅 (The modern home and living room)

Technology has changed how we interact with the home. Here at Google, we believe that the next leap forward in technology for the home will come from the intersection of hardware, software, and AI. We want people’s homes to be smarter, more helpful, and work for them.

科技改变了我们与家庭互动的方式。 在Google,我们相信家庭技术的下一个飞跃将来自硬件,软件和AI的交集。 我们希望人们的房屋更智能,更有用,并为他们工作。

This vision centers around Google Assistant, through its ability to bring together search and media contact points. And when we’re talking about media, there is no better place to consume media than the biggest screen in the home: the TV. Android TV is Google’s TV platform that brings media, games, and music together in one place.

通过将搜索和媒体联系点结合在一起的能力,这一愿景围绕Google Assistant展开。 当我们谈论媒体时,没有比家里最大的屏幕电视更好的消费媒体的地方了。 Android TV是Google的电视平台,可将媒体,游戏和音乐集中在一处。

Android TV is seeing great momentum: 7 of the 10 top smart TV manufacturers are shipping TVs with Android TV and over 160 pay TV operators are powering set top boxes with Android TV. This momentum extends to developers as well: there are around 7,000 apps on Google Play for Android TV, over 1,000 of which are from streaming content providers.

Android TV势头强劲:10家顶级智能电视制造商中有7家正在出货带Android TV的电视,而超过160家付费电视运营商正在为Android TV的机顶盒提供动力。 这种势头也扩展到了开发人员:用于Android TV的Google Play上大约有7,000个应用,其中有1,000多个来自流内容提供商。

是什么使Android应用成为Android TV应用? (What makes an Android app an Android TV app?)

Being Android means that you can reuse all of your skills as an Android developer to create an Android TV app, but what makes an Android app a TV app?

成为Android意味着您可以复用自己作为Android开发人员的所有技能来创建Android TV应用程序,但是什么使Android应用程序成为TV应用程序呢?

I’m going to start with the basics of the manifest file. Some of this may seem really basic but it is missed by many apps.

我将从清单文件的基础开始。 其中一些可能看起来真的很基础,但是许多应用程序都忽略了它。

First, you declare that you won’t be using a touch screen because people interact with their TVs through the remote control.

首先,您声明您将不会使用触摸屏,因为人们可以通过遥控器与电视进行互动。

<manifest xmlns:android="http://schemas.android.com/apk/res/android">


    <uses-feature
        android:name="android.hardware.touchscreen"
        android:required="false" />

Next, you declare that the app uses Leanback. This doesn’t specifically refer to the Leanback library: Leanback is a generic term used to define the experience of watching TV and experience where someone uses a device at a distance, in a Leanback position. Using this ensures that the app will only go on TV Google Play Store and not on any other surface like mobile, tablet, etc.

接下来,您声明该应用程序使用Leanback。 这并不是专门指Leanback库:Leanback是一个通用术语,用于定义观看电视的体验以及有人在Leanback位置远距离使用设备的体验。 使用此功能可确保该应用仅能在Google Play商店的电视上播放,而不能在手机,平板电脑等任何其他设备上播放。

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

Now you move on to declare the app’s banner.

现在,继续声明应用程序的横幅。

<application
        ...
        android:banner="@drawable/my_banner">

Before concluding by declaring the Android TV intent, which is not the main intent.

在结束之前,先声明Android TV意图,这不是主要意图。

<activity ... >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LEANBACK_LAUNCHER" />
            </intent-filter>
        </activity>
    
</manifest>

横幅 (The banner)

Your app’s banner is how people find it in the Android TV interface. Following best practices, your app’s banner should look something like this:

您的应用横幅是人们在Android TV界面中找到它的方式。 按照最佳做法,您应用的横幅应如下所示:

Image for post

However, we often see incorrect banners. A common mistake is using the same icon as the mobile app — typically a 512×512-pixel icon in the drawable-xhdpi folder — resulting in a scaled-down icon placed inside a dark rectangle.

但是,我们经常看到不正确的横幅。 一个常见的错误是使用与移动应用程序相同的图标(通常在drawable-xhdpi文件夹中为512×512像素的图标),导致缩小的图标放置在黑色矩形内。

The correct approach is to provide a 320×180-pixel icon in the /res/drawable-xhdpi folder. If you provide a banner larger than that, it doesn’t matter in which folder you put it; it’s not going to appear correctly.

正确的方法是在/ res / drawable-xhdpi文件夹中提供320×180像素的图标。 如果提供的横幅广告大于此大小,则将其放置在哪个文件夹中都没有关系; 它不会正确显示。

Remember that your banner is used as your app’s representation elsewhere too, such as in the Play Next channel, so getting it right is important.

请记住,横幅也被用作应用的其他表示形式,例如在Play Next频道中,因此正确设置它很重要。

Image for post

Google Play商店出版物 (Google Play Store publication)

You will want your app published in the Google Play Store for Android TV section. To do this, when submitting your app, in the Pricing & distribution section make sure you check the Distribute your app on Android TV.

您将希望您的应用发布在Android TV的Google Play商店部分。 为此,请在提交应用程序时在“ 定价和分发”部分中,确保选中了“ 在Android TV上分发应用程序”。

Image for post

We ask you to explicitly elect to distribute your app on Android TV to make sure that you’ve given careful consideration to how your app behaves on the big screen instead of simply detecting that an app has the leanback feature declared. For instance, some hybrid or multi-platform development tools simply enable this feature. However, apps created in these environments may never be tested for TV so they won’t necessarily work correctly on a TV.

我们要求您明确选择在Android TV上分发您的应用程序,以确保您已仔细考虑了应用程序在大屏幕上的行为,而不是简单地检测到某个应用程序声明了回溯功能。 例如,某些混合或多平台开发工具只是启用了此功能。 但是,在这些环境中创建的应用可能永远不会经过电视测试,因此它们不一定能在电视上正常运行。

Leanback库 (Leanback library)

The Leanback library is a set of high-level widgets that conform to the material design specs and provide a great experience when people view an app on a TV.

Leanback库是一组符合材料设计规范的高级小部件,当人们在电视上查看应用程序时可提供出色的体验。

Image for post

The widgets include those for the home screen — which contains, for example, channels (rows) and a navigation drawer — widgets for content details, and many others for different situations.

这些小部件包括用于主屏幕的小部件(例如,包含通道(行)和导航抽屉),这些小部件用于内容详细信息,而其他小部件则用于不同的情况。

There are two principal ways that the Leanback library can be customized for use in your app: change the colors and dimensions values or provide custom presenters.

可以自定义Leanback库以在应用程序中使用的两种主要方法:更改颜色和尺寸值或提供自定义演示者。

颜色和尺寸 (Colors and dimensions)

To illustrate how you can customize Leanback library content, let’s take the BrowseSupportFragment. This fragment is used in the home screen of many apps to show sidebar navigation and the channels of content. The fragment has methods and various properties in which you can modify the colors and dimensions, properties such as padding, title styles, and row styles.

为了说明如何自定义Leanback库内容,让我们使用BrowseSupportFragment。 许多应用程序的主屏幕都使用此片段,以显示侧边栏导航和内容通道。 该片段具有方法和各种属性,您可以在其中修改颜色和尺寸,属性(例如填充,标题样式和行样式)。

Similarly the navigation drawer, each of the individual cards, and so on have properties and methods that allow you to modify its appearance.

同样,导航抽屉,每个独立的卡等等,都具有允许您修改其外观的属性和方法。

Image for post
Customization of colors and dimensions
定制颜色和尺寸

定制演示者 (Custom presenters)

The Leanback library is based on the Model View Pattern (MVP) and many of its widgets enable you to provide a custom presenter. In MVP, your presenter acts as the glue between the model and the view but is also responsible for inflating the view.

Leanback库基于模型视图模式(MVP),并且其许多小部件都使您能够提供自定义演示者。 在MVP中,您的演示者充当模型和视图之间的粘合剂,但还负责扩大视图。

This behavior means that providing a custom presenter gives you complete control over the look of a widget. To show you how this works, let’s take the BrowseSupportFragment again.

此行为意味着提供自定义演示者可以使您完全控制小部件的外观。 为了向您展示这是如何工作的,让我们再次使用BrowseSupportFragment。

Image for post

This fragment expects an object adapter for it to show the individual list rows. The list rows, in turn, want a header item and an item adapter. Then there is the header item presenter, which is used to customize the look of the navigation drawer.

该片段需要一个对象适配器来显示各个列表行。 列表行又需要标题项目和项目适配器。 然后是标题项目演示者,用于自定义导航抽屉的外观。

Say, I want the navigation drawer to display icons close to the titles, like this:

说,我希望导航抽屉在标题附近显示图标,如下所示:

Image for post

In Kotlin, you use this code:

在Kotlin中,使用以下代码:

class IconHeaderItemPresenter : RowHeaderPresenter() {


    override fun onCreateViewHolder(viewGroup: ViewGroup): ViewHolder {
        // inflate layout
    }


    override fun onBindViewHolder(viewHolder: Presenter.ViewHolder, item: Any) {
        // set text, icons, etc.
    }


    override fun onUnbindViewHolder(viewHolder: Presenter.ViewHolder) {
        // free resources
    }


}

This code provides a custom presenter called IconHeaderItemPresenter by extending the RowHeaderPresenter. The code then overrides three functions:

该代码通过扩展RowHeaderPresenter提供了一个名为IconHeaderItemPresenter的自定义演示器。 然后,代码将覆盖三个功能:

  • onCreateViewHolder the inflator layout. Because this is a presenter, you inflate the layout within the presenter and you’re in complete control of providing any view that you want.

    onCreateViewHolder充气机布局。 因为这是一个演示者,所以您可以在演示者中为布局充气,并且可以完全控制提供所需的任何视图。
  • onBindViewHolder where you set the content.

    onBindViewHolder,您可以在其中设置内容。
  • onUnbindViewHolder where you free the resources.

    onUnbindViewHolder,您可以在其中释放资源。

This is the minimum set of functions you need to override to customize the presenter.

这是自定义演示者需要重写的最少功能集。

So, to add the icons you provide a custom view using a linear layout and including a text view, the default, and an image view.

因此,要添加图标,您可以使用线性布局提供自定义视图,包括文本视图,默认视图和图像视图。

<androidx.leanback.widget.NonOverlappingLinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">


    <ImageView
        android:id="@+id/header_icon"
        android:layout_width="32dp"
        android:layout_height="32dp"
        android:contentDescription="@string/header_icon" />


    <TextView
        android:id="@+id/header_label"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="6dp" />


</androidx.leanback.widget.NonOverlappingLinearLayout>

Then, in onBindViewHolder, get an instance of the ViewHolder presenter and the HeaderItem. By getting the HeaderItem, you can call properties such as getName and use those to fill the text view, label, and icon.

然后,在onBindViewHolder中,获取ViewHolder演示者和HeaderItem的实例。 通过获取HeaderItem,您可以调用诸如getName的属性,并使用这些属性来填充文本视图,标签和图标。

override fun onBindViewHolder(viewHolder: Presenter.ViewHolder, item: Any) {
    val headerItem = (item as ListRow).headerItem
    viewHolder.view.apply {
        (findViewById<View>(R.id.header_icon) as ImageView).apply {
            val drawableResId = when (headerItem.id) {
                ID_POPULAR -> R.drawable.ic_popular
                ID_EDITOR_PICKS -> R.drawable.ic_editor_picks
                ...
            }
            setImageDrawable(resources.getDrawable(drawableResId, null))
        }
        (findViewById<View>(R.id.header_label) as TextView).text = headerItem.name
    }
}

Then, you overwrite onUnbindViewHolder to free any resources used.

然后,您覆盖onUnbindViewHolder以释放所有使用的资源。

You can override other functions to customize their look and feel. To do this, back in your activity setHeaderPresentSelector and override with your custom presenter, in this case IconHeaderItemPresenter.

您可以覆盖其他功能以自定义其外观。 为此,请返回活动setHeaderPresentSelector并使用自定义演示者(在本例中为IconHeaderItemPresenter)进行覆盖。

setHeaderPresenterSelector(object : PresenterSelector() {
    override fun getPresenter(item: Any?) = IconHeaderItemPresenter()
})

Android TV整合 (Android TV integration)

So far you’ve learned about creating an app that is properly configured for Android TV and has the look and feel you want. The third step in creating a great Android TV app is integrating it with the features and functions of Android TV to help people discover your content and provide them with an engaging experience. I’m going to look at 4 of these integrations:

到目前为止,您已经了解了如何创建为Android TV正确配置并具有所需外观的应用程序。 创建出色的Android TV应用程序的第三步是将其与Android TV的特性和功能集成在一起,以帮助人们发现您的内容并为他们提供引人入胜的体验。 我将看一下其中的4种集成:

  • Assistant media controls

    辅助媒体控件
  • The Play Next channel

    下一播放频道
  • Android TV channels

    Android电视频道
  • Assistant media discovery

    辅助媒体发现

媒体控制 (Media controls)

It’s popular to control media playback on Android TV using voice. Your app can take advantage of this by integrating media sessions to handle the callbacks. Users will be able to perform actions such as:

使用语音控制Android TV上的媒体播放很流行。 您的应用可以通过集成媒体会话来处理回调来利用此优势。 用户将能够执行以下操作:

  • play and pause

    播放和暂停
  • skip to the previous channel

    跳到上一个频道
  • skip to the previous episode

    跳到上一集
  • skip the next item

    跳过下一项

If you’re using ExoPlayer to play media inside your app, you can get this functionality in just a few lines. Simply create a MediaSession, a MediaSessionConnector and connect it to your player:

如果您使用ExoPlayer在应用程序内部播放媒体,则只需几行即可获得此功能。 只需创建一个MediaSession,一个MediaSessionConnector并将其连接到播放器即可:

mediaSession = new MediaSessionCompat(this, "sample");
mediaSessionConnector = new MediaSessionConnector(mediaSession);
mediaSessionConnector.setPlayer(player);

You can find the dependencies you need for MediaSessionConnector here:https://github.com/google/ExoPlayer/tree/release-v2/extensions/mediasession

您可以在此处找到MediaSessionConnector所需的依赖项: https : //github.com/google/ExoPlayer/tree/release-v2/extensions/mediasession

To instead create this integration from scratch, provide your media session callback by extending MediaSessionCompat.Callback like this:

要从头开始创建此集成,请通过扩展MediaSessionCompat.Callback来提供媒体会话回调,如下所示:

class MyMediaSessionCallback: MediaSessionCompat.Callback {
    override fun onPause() { ... }
    override fun onPlay() { ... }
    override fun onStop() { ... }
    override fun onSeekTo(position: Long) { ... }
    override fun onSkipToNext() { ... }
    override fun onSkipToPrevious() { ... }}


mediaSession.setCallback(myMediaSessionCallback)

You can then override all of the functions: onPlay, onPause, onStop, onSeekTo, onSkipToNext, and onSkipToPrevious. You can also override all of the controls and control your own player.

然后,您可以覆盖所有功能:onPlay,onPause,onStop,onSeekTo,onSkipToNext和onSkipToPrevious。 您还可以覆盖所有控件并控制自己的播放器。

Whether you’re connecting to ExoPlayer or not, remember to set the MediaSession to active in accordance with how your app plays media in the background and don’t combine both approaches. Also be sure to release the MediaSession when playback stops.

无论您是否连接到ExoPlayer,请记住都要根据您的应用在后台播放媒体的方式将MediaSession设置为活动状态,并且不要同时使用这两种方法。 还要确保在播放停止时释放MediaSession。

By providing these callbacks to your media session instance, your app now responds to the Assistant playback controls. If Android TV is connected to an HDMI-CEC compliant device, it can even handle playback buttons from conventional TV remotes.

通过将这些回调提供给媒体会话实例,您的应用现在可以响应助手的播放控件。 如果将Android TV连接到兼容HDMI-CEC的设备,则它甚至可以处理传统TV遥控器上的播放按钮。

播放下一个频道 (Play Next channel)

Image for post

Coming immediately after the user’s favorite apps — the top-most row on the Android TV home screen — the Play Next channel is a global space for peoples’ content from apps. Your app can push content here: content someone didn’t finish watching or other content of interest, such as a movie they haven’t finished or the next episode of a series. As content is added, older content moves to the right and, if the user doesn’t interact with it, is eventually removed.

紧随用户喜欢的应用程序之后(Android TV主屏幕上的第一行),“播放下一个”频道是一个全球空间,人们可以从应用程序中获得内容。 您的应用可以在此处推送内容:未完成观看的内容或其他感兴趣的内容,例如未完成的电影或系列的下一集。 添加内容后,较旧的内容会移到右侧,如果用户不与之交互,则最终会被删除。

While you might be eager to get started, let’s set some ground rules of how apps must play nicely inside the Play Next channel. Content inside this space should be limited to traditional movies and TV shows, so avoid adding video clips, game posters or anything else that deviates. Content should also only appear if the user has invested a bit of time into watching, and you should be sure to remove entries when the content has finished (for instance, the end credits begin rolling).

尽管您可能很想入门,但让我们为在Play Next频道内如何良好运行应用设置一些基本规则。 该空间内的内容应仅限于传统电影和电视节目,因此请避免添加视频剪辑,游戏海报或其他有偏差的内容。 仅当用户花了一些时间观看时,内容才应显示,并且您应确保在内容完成后删除条目(例如,结束信用开始滚动)。

For using this space to recommend content to watch next, make sure that you only do so when adding the next TV episode of a series. In all cases, make sure to use the right “watch next type” and “program type”; doing so helps Android TV reconcile the asset more effectively and provides a high-confidence feature to users. Please read the Watch Next guidelines for app developers carefully before getting started with integrating into the Play Next channel.

为了利用此空间推荐下一个要观看的内容,请确保仅在添加电视剧的下一集时才这样做。 在所有情况下,请确保使用正确的“观看下一个类型”和“节目类型”; 这样做有助于Android TV更有效地协调资产,并为用户提供高度保密的功能。 在开始集成到Play Next频道之前,请仔细阅读面向应用开发者Watch Next指南

To add content to the row, you can publish WatchNextProgram to AndroidX’s PreviewChannelHelper. This uses a builder, so you don’t have to build or worry about the content provider. It’s recommended to add channels on a background thread.

要将内容添加到该行,您可以将WatchNextProgram发布到AndroidX的PreviewChannelHelper。 这使用了一个构建器,因此您不必构建或担心内容提供者。 建议在后台线程上添加频道。

val program = WatchNextProgram.Builder()

Use setWatchNextType — which could be a movie, a series, or music — to provide a title, description, and URI for poster art. If the content is an item someone has not finished viewing, you can include a progress bar below the content artwork, to show where they stopped viewing, by setting the last engagement time. It’s not recommended to add clips or short videos to Play Next Channel.

使用setWatchNextType(可能是电影,连续剧或音乐)来提供海报艺术的标题,描述和URI。 如果内容是某人尚未完成查看的项目,则可以在内容图稿下方包括一个进度条,以通过设置上次参与时间来显示他们停止查看的位置。 不建议将片段或短视频添加到“播放下一频道”。

.setWatchNextType(
             WatchNextPrograms.WATCH_NEXT_TYPE_CONTINUE)
         .setContentId(myProgramId)
         .setType(PreviewPrograms.TYPE_MOVIE)
         .setTitle("Program Title")
         .setDescription("Program Description")
         .setPosterArtUri(
             Uri.parse("http://example.com/poster_art.png"))
         .setLastEngagementTimeUtcMillis(System.currentTimeMillis())
Then you build
 
         .build()

Finally, use PreviewChannelHelper to call publishWatchNextProgram.

最后,使用PreviewChannelHelper调用publishWatchNextProgram。

PreviewChannelHelper(context).publishWatchNextProgram(program)

Android TV频道 (Android TV Channel)

Channels are the rows on the Android TV home screen that enable your app to recommend content. When you create an Android TV app, one channel is added by default but you can have as many channels as you want. However, for other channels, the user has to choose to add them to the home screen.

频道是Android TV主屏幕上的行,可让您的应用推荐内容。 创建Android TV应用时,默认情况下会添加一个频道,但您可以根据需要添加任意数量的频道。 但是,对于其他频道,用户必须选择将其添加到主屏幕。

Image for post
Source: Google
资料来源:谷歌

To add a channel, publish a PreviewChannel and PreviewPrograms to AndroidX’s PreviewChannelHelper. This also uses a builder, so you don’t have to worry about manually creating the content provider. For best performance, it’s recommended to execute this on a background thread.

要添加频道,请将PreviewChannel和PreviewPrograms发布到AndroidX的PreviewChannelHelper。 这也使用了一个构建器,因此您不必担心手动创建内容提供者。 为了获得最佳性能,建议在后台线程上执行此操作。

val helper = PreviewChannelHelper(context)

For the channel, you set the display name, description, and app link intent URI. You can, if you want, set an internal provider ID, a custom ID that you can set to retrieve later.

对于通道,您可以设置显示名称,描述和应用程序链接意图URI。 您可以根据需要设置内部提供程序ID,可以将其设置为以后检索的自定义ID。

val previewChannel = PreviewChannel.Builder()
        .setDisplayName(name)
        .setDescription(description)
        .setAppLinkIntentUri(Uri.parse(deeplinkUri))
        .setInternalProviderId(getPlaylistId())

Next, set a logo.

接下来,设置徽标。

.setLogo(bitmap)

Finally, build the PreviewChannel.

最后,构建PreviewChannel。

.build()

When you publish your channel by using the helper, you’re returned a channel ID assigned by Android TV.

使用帮助器发布频道时,您将返回由Android TV分配的频道ID。

val channelId = helper.publishChannel(previewChannel)

You can now use this channel ID in a preview builder to build a program.

现在,您可以在预览构建器中使用此频道ID来构建程序。

val program = PreviewProgram.Builder()
        .setChannelId(channelId)
        // Matches the intent filter in the manifest for VIEW action
        .setIntentUri(Uri.parse("https://.../program/$id"))
        .build()
helper.publishPreviewProgram(program)

最后的话 (Final words)

You’ve seen how to get a flying start with making an Android TV app, from getting the basics right to customizing the Leanback library and integrating with Android TV features to delight your users. Your app can have the look and feel that you want and people will be able to find and control your content directly on TV using Assistant. Now, all that’s left to do is create some great engaging media!

您已经了解了如何制作Android TV应用程序,从正确的基础知识到自定义Leanback库以及与Android TV功能集成以使您的用户满意,这是一个快速的开始。 您的应用可以具有所需的外观,人们可以使用Assistant直接在电视上查找和控制您的内容。 现在,剩下要做的就是创建一些出色的吸引人的媒体!

翻译自: https://medium.com/androiddevelopers/android-tv-best-practices-for-engaging-apps-acd0219ff395

android:tv直播

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值