Developer Console

Send Recommendations that Include Amazon Extras (Fire TV)

You create recommendations by creating ContentRecommendation objects through the ContentRecommendation.Builder() class. In addition to the attributes in this class, you can also include Amazon-specific extras to better integrate with Amazon Fire TV.

Here is a video that will walk you through the process. Fore more details, see the rest of the page below.

Creating Recommendations

Amazon's recommendations use the standard Android ContentRecommendation.Builder API. For full details, see the Android documentation on Recommending TV Content and the ContentRecommendation.Builder class.

In addition what's included in the Android documentation, you can expand the recommendations functionality in your notification objects with Amazon-specific extras. These extras help integrate the recommendations into Amazon Fire TV in deeper ways.

Sample Recommendation

Before diving into code examples, let's look at a sample recommendation card. The numbers show several attributes set through the Android API and one attribute set through an Amazon extra.

setTitle. Sets the title for the recommendation. (Android API)
setText. Sets the description for the recommendation. (Android API)
setContentImage. Sets the image used for the recommendation. (Android API)
Sets an abbreviated name for your app, which is used in the launch menu. This is set by one of the Amazon extra fields: com.amazon.extra.DISPLAY_NAME", "displayName".

For example, if your app has a long name, such as "World Premier Association Videos for Fire TV," this long title will be truncated in the launch menu. Instead of accepting the default truncation, you can specify the shortened name for your app through the Amazon extras (in this case, the DISPLAY_NAME).

The following screenshot shows how the AOL On app customized the text in the launch menu using Amazon extra fields.

Code Example for a Recommendation

The following code shows how to create a ContentRecommendation object and getNotificationObject that includes Amazon extras:

mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
//Sets an ID for the notification, so it can be updated
int notifyID = int_value;

ContentRecommendation rec = new ContentRecommendation.Builder()
        .setContentImage(myBitmap) // From API 23 this method also accepts Icon as argument.
        .setContentIntentData(ContentRecommendation.INTENT_TYPE_, mIntent, mRequestCode, mBundle) // For more information on setContentIntentData(), see 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) // This method won't have any influence on ratings on Fire TV. Use the com.amazon.extra.MATURITY_RATING setting instead.
        .setRunningTime(contentLength)
        .build();


Notification notification = rec.getNotificationObject(mContext);

//The additional Amazon extra values get added as follows:

//Assign a business name for the application which may be shown on the UI
notification.extras.putString("com.amazon.extra.DISPLAY_NAME", mDisplayName);

//Assign a Maturity rating to this recommendation
notification.extras.putString("com.amazon.extra.MATURITY_RATING", mMaturityRating);

//Specifies how recommendations from one app is ordered.
notification.extras.putInt("com.amazon.extra.RANK", mRank);

//Assign a long description to this recommendation
notification.extras.putString("com.amazon.extra.LONG_DESCRIPTION", mLongDescription);

//Assign a last watched time to this recommendation
notification.extras.putLong("com.amazon.extra.LAST_WATCHED_DATETIME", mLastWatchedTime);

//Assign a preview video or image URL of this recommendation
notification.extras.putString("com.amazon.extra.PREVIEW_URL", mPreviewUrl);

//Assign the UHD tag to put your recommendation on the 4K UHD row
ArrayList<String> tagList = new ArrayList<String>();
tagList.add("UHD");
notification.extras.putStringArrayList("com.amazon.extra.TAGS", tagList);

//Assign a Live Content to this recommendation.
notification.extras.putInt(com.amazon.extra.LIVE_CONTENT, 1);

//Assign Release date to this recommendation
notification.extras.putString(com.amazon.extra.CONTENT_RELEASE_DATE, "2016");

//Assign Caption availability to this recommendation
notification.extras.putInt(com.amazon.extra.CONTENT_CAPTION_AVAILABILITY, 1);

//Assign a customer rating to this recommendation
notification.extras.putInt(com.amazon.extra.CONTENT_CUSTOMER_RATING, 5);

//Assign a customer rating count to this recommendation
notification.extras.putInt(com.amazon.extra.CONTENT_CUSTOMER_RATING_COUNT, 10);

//Assign a imdbid to this recommendation
notification.extras.putString(com.amazon.extra.IMDB_ID, "tt0417148");

//Assign a start time of live content to this recommendation
notification.extras.putLong(com.amazon.extra.CONTENT_START_TIME, System.currentTimeMillis());

//Assign a end time of live content to this recommendation
notification.extras.putLong(com.amazon.extra.CONTENT_END_TIME, System.currentTimeMillis() + 10000);

mNotificationManager.notify(notifyID, notification);

The Amazon extras are added to the notification object. The values passed to the methods and extras (such as mText or mContext are assumed to be set elsewhere in the code. (For the sake of space, this part of the code isn't shown.) More information for using the Android recommendations API and Amazon extras are provided in the following sections.

Recommendations in Fire OS 7

As of Android Level 8.0 (API level 26), notifications that your app sends must be assigned to a channel. (Recommendations are a kind of notification.) If your app sends notifications or recommendations, you must create a channel and associate the channel with the notification. A notification without a channel ID will be dropped.

At a high-level, to add a channel to a notification, you do the following:

  1. Step 1: Create the notification channel and register it with the notification manager.
  2. Step 2: Set the channel ID for the notification, using one of the following methods:

The following sections provide more detail and code samples.

Step 1: Create the notification channel and register it with the notification manager

The following is from Create a notification channel in the Android documentation:

Create a notification channel

To create a notification channel, follow these steps:

  1. Construct a NotificationChannel object with a unique channel ID, a user-visible name, and an importance level.
  2. Optionally, specify the description that the user sees in the system settings with setDescription.
  3. Register the notification channel by passing it to createNotificationChannel.

    private void createNotificationChannel() {
        // Create the NotificationChannel, but only on API 26+ because
        // the NotificationChannel class is new and not in the support library
        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);
            // Register the channel with the system; you can't change the importance
            // or other notification behaviors after this
            NotificationManager notificationManager = getSystemService(NotificationManager.class);
            notificationManager.createNotificationChannel(channel);
        }
    }
    

Step 2: Set the Channel ID for the Notification

You have two options for setting the channel ID for the notification. You can either use ContentRecommendation and use reflection to set the channel ID, or you can use Notification.Builder.

Option 1: Use createContentRecommendation and use reflection to set the channel 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);
    }
}

Option 2: Use Notification.Builder with channel ID

Note that the following code is adapted from the Android Open Source Project on Google Git.

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

    // Encode all the content recommendation data in a Notification object

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

For more details, consult the Android documentation on Create and Manage Notification Channels.

Recommended Attributes for Android API code

Follow these guidelines when using the ContentRecommendation.Builder from the Android API. These guidelines will help your recommendations align with the look and feel of Amazon Fire TV.

API Description Required
setTitle(java.lang.String) "Sets the content title for the recommendation."

The length limit is 125 characters. Additional text is truncated.

Yes
setText(java.lang.String) "Sets the description text for the recommendation."

The length limit is 125 characters. Additional text is truncated.

Yes
setContentImage(Bitmap image) "Sets the recommendation image."

Use the following specifications for the large icon image:

  • Dimensions: 252px tall or more
  • Aspect ratio: 16:9
  • Title: Embedded within image
  • Transparency: No transparency

Recommendations without images either won't be displayed or will receive a default placeholder instead. Images with an aspect ratio other than 16:9 will be letterboxed. (Letterboxing means black bars will appear along the sides or top to compensate for the empty space.) Images larger than the specified dimensions will be scaled down to fit the space, preserving the 16:9 aspect ratio.

Yes
setContentIntentData(int intentType, Intent intent, int requestCode, Bundle options) "Sets the data for the Intent that will be issued when the user clicks on the recommendation. The Intent data fields provided correspond to the fields passed into the PendingIntent factory methods, when creating a new PendingIntent. The actual PendingIntent object will only be created at the time a recommendation is posted to the Home Screen." Yes
setBadgeIcon(int iconResourceId) "Sets the resource ID for the recommendation badging icon. The resource id represents the icon resource in the source application package. If not set, or an invalid resource ID is specified, the application icon retrieved from its package will be used by default." Yes
setGenres(String[] genres) "Sets the content genres for the recommendation. These genres may be used for content ranking. Genres are open ended String tags. Some examples: 'comedy', 'action', 'dance', 'electronica', 'racing', etc."

Use the standard Android genres.

No
setContentTypes(String[] types) "Sets the content types associated with the content recommendation. The first tag entry will be considered the primary type for the content and will be used for ranking purposes. Other secondary type tags may be provided, if applicable, and may be used for filtering purposes."

Only standard Android content recommendation categories are allowed.

No
setProgress(int max, int progress) "Sets the progress information for the content pointed to by the recommendation."

The progress amount for the content must be in the range (0 - max). The unit is seconds.

No
setRunningTime(long length) "Sets the running time (when applicable) for the content." Yes

Amazon Enhancements to Recommendations

The following table lists extras that you can add to your notification objects.

Extra name Data type Details Used
com.amazon.extra.DISPLAY_NAME String A shorter app name displayed in the Launch menu (which appears when you press the menu button while a recommendation is selected). The length limit is 15 characters. Additional characters are truncated without showing an ellipses for the truncated characters. Yes
com.amazon.extra.MATURITY_RATING String Displays the rating below the title. The rating is also used by the Parental Control settings on Amazon Fire TV to determine if content playback needs to be behind a PIN. Any recommendation without this extra or without a value for setMaturityRating() will be treated as Mature content and may require a PIN subject to the Parental Control settings on the device.

Currently, supported values are as follows:

  • US Marketplace: G, PG, PG13, R, NC17, NR, TVY, TVY7, TVG, TVPG, TV14, TVMA
  • German Marketplace: FSK0, FSK6, FSK12, FSK16, FSK18
  • Great Britain Marketplace: BBFCPG, BBFC12, BBFC18, BBFCU
  • Japan Marketplace: EIRIN_G, EIRIN_PG12, EIRIN_R15, EIRIN_18
  • India Marketplace:ALL, 7+, 13+, 16+, 18+, NR
Yes
com.amazon.extra.ACTION_OPTION ArrayList<int> Determines the context menu options displayed for each recommendation. Two context menu actions are supported, but only the first action is configurable.

When users click a recommendation tile or its first context menu option, Amazon Fire TV uses the corresponding content intent data passed with recommendation to launch the app. Note: If your app is providing an action array list, the com.amazon.extra.DISPLAY_NAME (mentioned above) is required.

Possible values to include for the ACTION_OPTIONare as follows:

  • 1: Watch with <App name>
  • 101: Watch
  • 2: Resume with <App name>
  • 102: Resume
  • 3: Switch <App name> Profile
  • 4: Change <App name> Settings
  • 104: Change Settings
  • 5: View with <App name>
  • 105: View
  • 6: Play with <App name>
  • 106: Play
  • 7: Listen with <App name>
  • 107: Listen

If no value is provided, the default action will be Open and below that, Launch <App Name>.

Yes
com.amazon.extra.RANK int This extra is used to sort items in ascending order by rank, after which they are subsorted by time of submission (most recent first). If absent, time of submission is used alone. Possible values range from 0 to INTEGER.MAX_VALUE. The lower the value, the higher the rank; that is, low values appear ahead of high values No
com.amazon.extra.CONTENT_ID String This id corresponds to the content id used in Catalog Integration. No
com.amazon.extra.LIVE_CONTENT int Helps determine whether a recommendation is live content and needs to be displayed or hidden based on CONTENT_START_TIME and CONTENT_END_TIME. Supported values are as follows:
  • 0: Not a Live content
  • 1: Live Content
No
com.amazon.extra.CONTENT_RELEASE_DATE String Content release year. Example: 2016, 2015, 1977 etc. Yes
com.amazon.extra.CONTENT_CAPTION_AVAILABILITY int Caption availability of content.
  • 0: Caption not available for content
  • 1: Caption available for content
Yes
com.amazon.extra.IMDB_ID String IMDB ID of content. (For example, if the URL is http://www.imdb.com/title/tt0417148, the ID is tt0417148.) No
com.amazon.extra.CONTENT_START_TIME long Start time of live content in milliseconds (EPOCH). No
com.amazon.extra.CONTENT_END_TIME long End time of live content in milliseconds (EPOCH). No
com.amazon.extra.LONG_DESCRIPTION String Long description of a recommendation. Length is limited to 512 characters. No
com.amazon.extra.LAST_WATCHED_DATETIME long Last watched time of the recommended content in milliseconds (EPOCH). No
com.amazon.extra.PREVIEW_URL String Preview video or image URL for the recommendation. No
com.amazon.extra.TAGS ArrayList<String> If your content is 4K (Ultra HD), add the tag ["UHD"]. Yes
com.amazon.extra.CONTENT_CUSTOMER_RATING int Customer rating, possible values range from 0 to 10. Yes
com.amazon.extra.CONTENT_CUSTOMER_RATING_COUNT int Number of customers rated this content. Yes

Configuring the Manifest

To send recommendations when the device boots up, your app must have the RECEIVE_BOOT_COMPLETED permission. This permission lets your app receive and handle the broadcast that tells the app your device was booted.

To receive the broadcast, add the following permission (to your Android Manifest) as a child of the <manifest> element:

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

The initial launch point for supporting recommendations is to create a subclass of BroadcastReceiver. In the manifest, register the receiver as handling the ACTION_BOOT_COMPLETED intent. When the system first boots up, all applications that are interested will get an initial 'ping' to generate their recommendations. For more details, see this How to Start an Application at Device Bootup in Android tutorial on Stacktips.com.

For the broadcast to work reliably, make sure your app is not installed on external storage. Refer to the following for more details about storage locations:

Delete Recommendations

As a best practice, delete recommendations after users watch the recommended content. You can call cancel() for a specific notification ID to delete the recommendation.

The following code sample shows how to delete recommendations:

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

//Use the same notification id which you used while creating this notification
mNotificationManager.cancel(notifyID);

Next steps

To learn more, see the following:


Last updated: Mar 26, 2021