开发者控制台

发送包含亚马逊额外信息的推荐

发送包含亚马逊额外信息的推荐

您可以通过ContentRecommendation.Builder()类创建ContentRecommendation对象,从而创建推荐。除了此类中的属性外,您还可以包含亚马逊特定的额外信息,以便更好地与Amazon Fire TV集成。

此视频将指导您完成这个过程(附带中文字幕)。更多详细信息,请参阅页面下方的剩余部分。

创建推荐

亚马逊的推荐使用标准Android ContentRecommendation.Builder API。有关完整详细信息,请参阅有关推荐电视内容ContentRecommendation.Builder类的Android文档。

除了Android文档中包含的内容外,您还可以通过亚马逊特定的额外信息扩展通知对象中的推荐功能。这些额外信息有助于以更深入的方式将推荐集成到Amazon Fire TV中。

示例推荐

在深入探讨代码示例之前,让我们来看一个示例推荐卡。这些数字显示通过Android API设置的多个属性以及通过亚马逊额外信息设置的一个属性。

setTitle。设置推荐的标题。(Android API)
setText。设置推荐的描述。(Android API)
setContentImage。设置用于推荐的图像。(Android API)
设置应用的缩写名称,该名称在启动菜单中使用。这由亚马逊的额外信息字段之一设置:com.amazon.extra.DISPLAY_NAME", "displayName"

例如,如果您的应用具有长名称,如“Fire TV世界顶级协会视频”,则此长标题将在启动菜单中被截断。您可以通过亚马逊额外信息(在本例中为DISPLAY_NAME)为您的应用指定缩短名称,而不是接受默认截断。

以下屏幕截图显示了AOL On应用如何使用亚马逊extra字段自定义启动菜单中的文本。

推荐的代码示例

以下代码显示了如何创建ContentRecommendation对象和包含亚马逊额外信息的getNotificationObject

mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
//设置通知ID,以便它可以更新
int notifyID = int_value;

ContentRecommendation rec = new ContentRecommendation.Builder()
        .setContentImage(myBitmap) // 从API 23,此方法也接受图标作为参数。
        .setContentIntentData(ContentRecommendation.INTENT_TYPE_, mIntent, mRequestCode, mBundle) // 有关setContentIntentData()的更多信息,请参阅https://developer.android.com/reference/android/support/app/recommendation/ContentRecommendation.html
        .setText(mText)
        .setTitle(mTitle)
        .setBadgeIcon(R.drawable.<app_icon>)
        .setGenres(mGenres)
        .setContentTypes(mTypes)
        .setProgress(mMaxLength,mProgress)
        .setMaturityRating(mMaturityRating) // 此方法不影响Fire TV上的评级。改用com.amazon.extra.MATURITY_RATING设置。
        .setRunningTime(contentLength)
        .build();


Notification notification = rec.getNotificationObject(mContext);

//其他亚马逊额外信息值将按如下所示添加:

//为应用分配一个可能显示在UI上的业务名称
notification.extras.putString("com.amazon.extra.DISPLAY_NAME", mDisplayName);

//为此推荐分配一个年龄评级
notification.extras.putString("com.amazon.extra.MATURITY_RATING", mMaturityRating);

//指定对来自一个应用的推荐进行排序的方式。
notification.extras.putInt("com.amazon.extra.RANK", mRank);

//为此推荐分配一个长描述
notification.extras.putString("com.amazon.extra.LONG_DESCRIPTION", mLongDescription);

//为此推荐分配最后一次观看时间
notification.extras.putLong("com.amazon.extra.LAST_WATCHED_DATETIME", mLastWatchedTime);

//指定此推荐的预览视频或图像URL
notification.extras.putString("com.amazon.extra.PREVIEW_URL", mPreviewUrl);

//分配超高清标签以将您的推荐放在4K超高清行上
ArrayList<String> tagList = new ArrayList<String>();
tagList.add("UHD");
notification.extras.putStringArrayList("com.amazon.extra.TAGS", tagList);

//为此推荐分配一个直播内容。
notification.extras.putInt(com.amazon.extra.LIVE_CONTENT, 1);

//为此推荐指定发布日期
notification.extras.putString(com.amazon.extra.CONTENT_RELEASE_DATE, "2016");

//为此推荐分配字幕可用性
notification.extras.putInt(com.amazon.extra.CONTENT_CAPTION_AVAILABILITY, 1);

//为此推荐分配一个客户评级
notification.extras.putInt(com.amazon.extra.CONTENT_CUSTOMER_RATING, 5);

//为此推荐分配一个客户评级计数
notification.extras.putInt(com.amazon.extra.CONTENT_CUSTOMER_RATING_COUNT, 10);

//为此推荐分配一个imdbid
notification.extras.putString(com.amazon.extra.IMDB_ID, "tt0417148");

//为此推荐分配直播内容的开始时间
notification.extras.putLong(com.amazon.extra.CONTENT_START_TIME, System.currentTimeMillis());

//为此推荐分配直播内容的结束时间
notification.extras.putLong(com.amazon.extra.CONTENT_END_TIME, System.currentTimeMillis() + 10000);

mNotificationManager.notify(notifyID, notification);

亚马逊额外信息将添加到通知对象中。传递给方法和额外信息(如mTextmContext)的值假定在代码中的其他位置设置。(因为空间原因,未显示代码的这一部分。) 有关使用Android推荐API和亚马逊额外信息的更多信息,请参阅以下部分。

Fire OS 7中的推荐

从Android Level 8.0(API级别26)开始,必须为应用发送的通知分配一个通道。(推荐是一种通知。) 若应用发送通知或推荐,必须创建一个通道并将通道与通知关联。没有通道ID的通知将被删除。

从更高层次上说,如需向通知添加通道,需进行以下操作:

  1. 步骤1: 创建通知通道,并在通知管理器中注册
  2. 步骤2: 设置通知的通道ID,使用以下方法之一:

以下章节提供更多详细信息和代码示例。

步骤1: 创建通知通道,并在通知管理器中注册

以下内容来自Android文档中的创建通知通道

创建通知通道

如需创建通知通道,请进行以下步骤:

  1. 构建具有唯一通道ID、用户可见名称和重要性级别的NotificationChannel对象。
  2. 或使用setDescription指定用户在系统设置中看到的描述。
  3. 通过将通知通道传递给createNotificationChannel,注册通知通道。

    private void createNotificationChannel() {
        //创建通知通道,但仅限于API 26+,因为
        // NotificationChannel类是新的,不在支持库中
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            CharSequence name = getString(R.string.channel_name);
            String description = getString(R.string.channel_description);
            int importance = NotificationManager.IMPORTANCE_DEFAULT;
            NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
            channel.setDescription(description);
            //在系统中注册通道;无法更改重要性
            //或之后其他通知行为
            NotificationManager notificationManager = getSystemService(NotificationManager.class);
            notificationManager.createNotificationChannel(channel);
        }
    }
    

步骤2: 设置通知的通道ID

有两个方法可用于设置通知的通道ID。可使用ContentRecommendation和反射,设置通道ID,也可以使用Notification.Builder

方法1: 通过使用createContentRecommendation和反射,设置通道ID

Notification notification = createContentRecommendation(largeIcon, notificationId);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    Log.d(TAG, "SDK version is >= Android O");

    try {
        Field channel = notification.getClass().getDeclaredField("mChannelId");
        channel.setAccessible(true);
        channel.set(notification, StringTerms.CHANNEL_ID);
    }
    catch (Exception e) {
        Log.d(TAG, "Can't set ChannelId", e);
    }
}

方法2: 将Notification.Builder与通道ID结合使用

请注意,以下代码是由Google Git上的Android开源项目改编而成。

public Notification getNotificationObject(Context context) {
    Notification.Builder builder = new Notification.Builder(context, "channelId");
    RecommendationExtender recExtender = new RecommendationExtender();

    // 对通知对象中的所有内容推荐数据进行编码

    builder.setCategory(Notification.CATEGORY_RECOMMENDATION);
    builder.setContentTitle(mTitle);
    builder.setContentText(mText);
    builder.setContentInfo(mSourceName);
    builder.setLargeIcon(mContentImage);
    builder.setSmallIcon(mBadgeIconId);
    if (mBackgroundImageUri != null) {
        builder.getExtras().putString(Notification.EXTRA_BACKGROUND_IMAGE_URI, mBackgroundImageUri);
    }
    builder.setColor(mColor);
    builder.setGroup(mGroup);
    builder.setSortKey(mSortKey);
    builder.setProgress(mProgressMax, mProgressAmount, false);
    builder.setAutoCancel(mAutoDismiss);

    if (mContentIntentData != null) {
        PendingIntent contentPending;
        if (mContentIntentData.mType == INTENT_TYPE_ACTIVITY) {
            contentPending = PendingIntent.getActivity(context, mContentIntentData.mRequestCode,
            mContentIntentData.mIntent, PendingIntent.FLAG_UPDATE_CURRENT,
            mContentIntentData.mOptions);
        }
        else if (mContentIntentData.mType == INTENT_TYPE_SERVICE) {
            contentPending = PendingIntent.getService(context, mContentIntentData.mRequestCode,
            mContentIntentData.mIntent, PendingIntent.FLAG_UPDATE_CURRENT);
            }
            else { // Default:INTENT_TYPE_BROADCAST{
            contentPending = PendingIntent.getBroadcast(context,
            mContentIntentData.mRequestCode,
            mContentIntentData.mIntent, PendingIntent.FLAG_UPDATE_CURRENT);
            }
        builder.setContentIntent(contentPending);
    }

    if (mDismissIntentData != null) {
        PendingIntent dismissPending;
        if (mDismissIntentData.mType == INTENT_TYPE_ACTIVITY) {
            dismissPending = PendingIntent.getActivity(context, mDismissIntentData.mRequestCode,
            mDismissIntentData.mIntent, PendingIntent.FLAG_UPDATE_CURRENT,
            mDismissIntentData.mOptions);
        }
        else if (mDismissIntentData.mType == INTENT_TYPE_SERVICE) {
            dismissPending = PendingIntent.getService(context, mDismissIntentData.mRequestCode,
            mDismissIntentData.mIntent, PendingIntent.FLAG_UPDATE_CURRENT);
            }
            else { // Default:INTENT_TYPE_BROADCAST{
                dismissPending = PendingIntent.getBroadcast(context,
                mDismissIntentData.mRequestCode,
                mDismissIntentData.mIntent, PendingIntent.FLAG_UPDATE_CURRENT);
            }
        builder.setDeleteIntent(dismissPending);
    }

    recExtender.setContentTypes(mContentTypes);
    recExtender.setGenres(mContentGenres);
    recExtender.setPricingInformation(mPriceType, mPriceValue);
    recExtender.setStatus(mStatus);
    recExtender.setMaturityRating(mMaturityRating);
    recExtender.setRunningTime(mRunningTime);

    builder.extend(recExtender);
    Notification notif = builder.build();
    return notif;
}

有关更多详细信息,请参阅关于创建和管理通知通道的Android文档。

Android API代码的推荐属性

使用Android API中的ContentRecommendation.Builder时,请遵循以下指南。这些指南将帮助您的推荐与Amazon Fire TV的外观和风格保持一致。

API 描述 必需
setTitle(java.lang.String) “设置推荐的内容标题。”

长度限制为125个字符。其他文本将被截断。

setText(java.lang.String) “设置推荐的描述文本。”

长度限制为125个字符。其他文本将被截断。

setContentImage位图图像 “设置推荐的图像。”

对于大图标图像,请使用以下规格:

  • 尺寸: 252像素高或更高
  • 宽高比: 16:9
  • 标题: 嵌入在图像中
  • 透明度: 不透明

没有图像的推荐将不会显示,或者将收到默认占位符。宽高比不是16:9的图像将采用信箱模式。(宽银幕边框模式是指两侧或顶部会出现黑条,以补偿空白空间。) 大于指定尺寸的图像将缩小以适应空间,并保持16:9的宽高比。

setContentIntentData(int intentType、Intent意图、int requestCode、Bundle选项 “设置用户单击推荐时将发布的意图数据。在创建新的PendingIntent时,提供的“意图”数据字段对应于传递到PendingIntent工厂方法的字段。实际的PendingIntent对象仅在推荐发布到主屏幕时才会创建。”
setBadgeIcon(int iconResourceId) ”设置推荐落款图标的资源ID。资源ID表示源应用程序包中的图标资源。如果未设置,或者指定了无效的资源ID,则默认情况下将使用从其程序包中检索的应用图标。”
setGenres(String[] genres) “设置推荐的内容类型。这些类型可用于内容排名。类型是开放式字符串标签。一些例子:'comedy'、'action'、'dance'、'electronica'、'racing'等。”

使用标准的Android类型。

setContentTypes(String[] types) “设置与内容推荐关联的内容类型。第一个标签条目将被视为内容的主要类型,并将用于排名目的。如果适用,可以提供其他辅助类型标签,并将其用于筛选目的。”

仅允许使用标准Android内容推荐类别

setProgress(int max, int progress) “设置推荐指向的内容的进度信息。”

内容的进度必须在(0 - max)范围内。单位是秒。

setRunningTime(long length) “设置内容的运行时间(如果适用)。”

亚马逊对推荐的改进

下表列出了可以添加到通知对象的额外信息。

额外项名称 数据类型 详情 已使用
com.amazon.extra.DISPLAY_NAME 字符串 “启动”菜单中显示的较短应用名称(在选择推荐时按菜单按钮会显示该名称)。长度限制为15个字符。其他字符将被截断,且被截断字符不会显示为省略号。
com.amazon.extra.MATURITY_RATING 字符串 在标题下方显示评级。Amazon Fire TV上的“家长监护”设置也使用该评级来确定播放内容是否需要PIN。任何没有此额外信息或者没有setMaturityRating()值的推荐将被视为成人内容,可能需要PIN码才能播放,具体取决于设备上的“家长监护”设置。

目前,支持的值如下所示:

  • 美国市场: GPGPG13RNC17NRTVYTVY7TVGTVPGTV14TVMA
  • 德国市场: FSK0FSK6FSK12FSK16FSK18
  • 英国市场: BBFCPGBBFC12BBFC18BBFCU
  • 日本市场: EIRIN_GEIRIN_PG12EIRIN_R15EIRIN_18
  • 印度市场:ALL7+13+16+18+NR
com.amazon.extra.ACTION_OPTION ArrayList<int> 确定为每个推荐显示的上下文菜单选项。支持两个上下文菜单操作,但只有第一个操作是可配置的。

当用户单击推荐磁贴或其第一个上下文菜单选项时,Amazon Fire TV会使用随推荐传递的相应内容意图数据启动应用。注意:​ 如果您的应用提供了操作数组列表,则必须提供com.amazon.extra.DISPLAY_NAME(如上所述)。

ACTION_OPTION包含的可能值如下所示:

  • 1: 使用<应用名称>观看
  • 101: 观看
  • 2: 使用<应用名称>继续
  • 102: 继续
  • 3: 切换<应用名称>配置文件
  • 4: 更改<应用名称>设置
  • 104: 更改设置
  • 5: 使用<应用名称>查看
  • 105: 查看
  • 6: 使用<应用名称>播放
  • 106: 播放
  • 7: 使用<应用名称>收听
  • 107: 收听

如果未提供任何值,则默认操作将为打开,且下面是启动<应用名称>

com.amazon.extra.RANK int 这个额外项用于按排名的升序顺序排列项目,然后按提交时间进行二次排序(最新提交的最先列出)。如果缺少此值,则只按提交时间排序。可能值范围为0到INTEGER.MAX_VALUE。值越低,排名越高;也就是说,低值在高值之前显示
com.amazon.extra.CONTENT_ID 字符串 此ID对应于目录集成中使用的内容ID。
com.amazon.extra.LIVE_CONTENT int 根据CONTENT_START_TIMECONTENT_END_TIME帮助确定推荐是否为直播内容,以及是需要显示还是隐藏。支持的值如下:
  • 0: 非直播内容
  • 1: 直播内容
com.amazon.extra.CONTENT_RELEASE_DATE 字符串 内容发布年份。示例: 2016、2015、1977等。
com.amazon.extra.CONTENT_CAPTION_AVAILABILITY int 内容的字幕可用性。
  • 0: 内容没有字幕可用
  • 1: 内容有字幕可用
com.amazon.extra.IMDB_ID 字符串 内容的IMDB ID。(例如,如果URL为http://www.imdb.com/title/tt0417148,则该ID为tt0417148。)
com.amazon.extra.CONTENT_START_TIME long 直播内容的开始时间(以毫秒为单位)(EPOCH)。
com.amazon.extra.CONTENT_END_TIME long 直播内容的结束时间(以毫秒为单位)(EPOCH)。
com.amazon.extra.LONG_DESCRIPTION 字符串 推荐的详细描述。长度限制为512个字符。
com.amazon.extra.LAST_WATCHED_DATETIME long 推荐内容的上次观看时间(以毫秒为单位)(EPOCH)。
com.amazon.extra.PREVIEW_URL 字符串 推荐的预览视频或图像URL。
com.amazon.extra.TAGS ArrayList<String> 如果您的内容是4K(超高清),请添加标签["UHD"]
com.amazon.extra.CONTENT_CUSTOMER_RATING int 客户评分,可能值范围为0到10。
com.amazon.extra.CONTENT_CUSTOMER_RATING_COUNT int 对此内容进行评分的客户数量。

配置清单

要在设备启动时发送推荐,您的应用必须具有RECEIVE_BOOT_COMPLETED权限。此权限允许您的应用接收和处理告知应用您的设备已启动的广播。

要接收广播,请将以下权限作为<manifest>元素的子项添加到Android清单:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

支持性推荐的初始启动点是创建BroadcastReceiver的一个子类。在清单中,将接收方注册为处理ACTION_BOOT_COMPLETED意图。系统首次启动时,所有相关应用都会获得一个初始的“ping”来生成推荐。有关更多详细信息,请参阅Stacktips.com上的如何在设备启动时启动Android系统中的应用教程。

为了使广播可靠工作,请确保您的应用未安装在外部存储器上。有关存储位置的详细信息,请参阅以下内容:

删除推荐

最佳实践是在用户观看推荐内容后删除推荐。您可以为特定通知ID调用cancel()来删除推荐。

以下代码示例显示如何删除推荐:

mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

//使用您在创建此通知时使用的相同通知ID
mNotificationManager.cancel(notifyID);

后续步骤

要了解更多信息,请参阅以下内容: