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.
- Creating Recommendations
- Sample Recommendation
- Code Example for a Recommendation
- Recommendations in Fire OS 7
- Send Recommendations for AOSP 14
- Recommended Attributes for Android API code
- Amazon Enhancements to Recommendations
- Configuring the Manifest
- Delete Recommendations
- Next steps
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.
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
dependencies
block of your app's build.gradle file.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:
- Step 1: Create the notification channel and register it with the notification manager.
- 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:
- Construct a
NotificationChannel
object with a unique channel ID, a user-visible name, and an importance level.- Optionally, specify the description that the user sees in the system settings with
setDescription
.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.
Send Recommendations for AOSP 14
Use the following guidance to send recommendations to add devices running Android Open Source Project (AOSP) 14.
Make sure it's compatible
The home screen accepts recommendations from apps in two different ways depending on the Fire OS version:
- In AOSP 14 (API level 34) and later, apps must follow the Fire OS recommendation guide and use the TV Provider library.
- Before AOSP 14, apps still follow the Fire OS 7 recommendations guide and use
NotificationChannel
andNotification
classes to send recommendations.
To be able to show recommendations on all versions of Fire OS, implement both recommendation APIs. Test the current system API level and use the appropriate API to build recommendations.
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
// Use AOSP 14 recommendation guide
} else {
// Use Fire OS 7 recommendation guide
}
Use TVProvider for sending recommendation
On AOSP 14, Amazon’s recommendation adopts the Android TV recommendation library (i.e. TV Provider) for sending recommendations to the “RECOMMENDED BY YOUR APPS” row. For full details about sending recommendations, see the Android documentation on Channels on the home screen, Channel
, and PreviewProgram
classes.
Code Example for a Recommendation on AOSP 14
In order to create a recommendation you would need to perform 2 steps:
- Create the recommendation channel
- Send the recommendation to the channel using the channel ID
Step 1: Create the recommendation channel
- Create a Channel.Builder and set its attributes.
- Insert the channel into the provider.
- Save the channel ID in order to add programs to the channel later.
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")
Uri channelUri = context.getContentResolver().insert(
TvContractCompat.Channels.CONTENT_URI, builder.build().toContentValues());
// This Channel ID can be stored and used later to update the Channel
// Or to add Programs to it
long channelId = ContentUris.parseId(channelUri);
val builder = Channel.Builder()
// Every channel you create must have the type TYPE_PREVIEW
builder.setType(TvContractCompat.Channels.TYPE_PREVIEW)
.setDisplayName("Channel Name")
val channelUri = context.contentResolver.insert(
TvContractCompat.Channels.CONTENT_URI, builder.build().toContentValues()
)
// This Channel ID can be stored and used later to update the Channel
// Or to add Programs to it
val channelId = ContentUris.parseId(channelUri)
Step 2: Send the recommendation to the channel
- Create a PreviewProgram.Builder and set its attributes.
- Insert the program into the provider.
- Optionally, retrieve the program ID for later reference.
// The additional optional Amazon extra values get added as follows
// Creating a Bundle
Bundle bundle = new Bundle();
bundle.putInt("com.amazon.extra.CONTENT_CAPTION_AVAILABILITY", 1);
bundle.putString("com.amazon.extra.DISPLAY_NAME", "display_name");
bundle.putInt("com.amazon.extra.ACTION_OPTION", 1);
// Converting Bundle to byte array (Blob)
Parcel parcel = Parcel.obtain();
bundle.writeToParcel(parcel, 0);
byte[] extrasBlob = parcel.marshall();
parcel.recycle(); // Recycle the parcel after use
// Sending Recommendation
PreviewProgram.Builder builder = new PreviewProgram.Builder();
builder.setChannelId(channelId)
.setType(TvContractCompat.PreviewPrograms.TYPE_MOVIE)
.setTitle("Title")
.setDescription("Program description")
.setPosterArtUri(uri)
.setIntentUri(uri)
.setInternalProviderData(extrasBlob);
Uri programUri = context.getContentResolver().insert(TvContractCompat.PreviewPrograms.CONTENT_URI,
builder.build().toContentValues());
// This Program ID can be used to update the Program later
long programId = ContentUris.parseId(programUri);
// The additional optional Amazon extra values get added as follows:
// Creating a Bundle
val extras = Bundle().apply {
putInt("com.amazon.extra.CONTENT_CAPTION_AVAILABILITY", 1)
putString("com.amazon.extra.DISPLAY_NAME", "display_name");
putInt("com.amazon.extra.ACTION_OPTION", 1)
}
// Converting Bundle to byte array (Blob)
val parcel = Parcel.obtain()
bundle.writeToParcel(parcel, 0)
val extrasBlob = parcel.marshall()
parcel.recycle() // Recycle the parcel after use
val builder = PreviewProgram.Builder()
.setChannelId(channelId)
.setType(TvContractCompat.PreviewPrograms.TYPE_MOVIE)
.setTitle("Title")
.setDescription("Program description")
.setPosterArtUri(uri)
.setIntentUri(uri)
.setInternalProviderData(extrasBlob)
val programUri = context.contentResolver.insert(TvContractCompat.PreviewPrograms.CONTENT_URI,
builder.build().toContentValues())
// This Program ID can be used to update the Program later
val programId = ContentUris.parseId(programUri)
Recommended Attributes for Android API code
Follow these guidelines when using the PreviewProgram.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 title) |
Sets the content title for the recommendation. The length limit is 125 characters. Additional text is truncated. | Yes |
setDescription(java.lang.String description) |
Sets the description text for the recommendation. The length limit is 125 characters. Additional text is truncated. | Yes |
setThumbnailUri(Uri thumbnailUri) |
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 |
setContentRatings(TvContentRating contentRatings[]) |
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 value will be treated as Mature content and may require a PIN subject to the Parental Control settings on the device.Currently supported values mentioned in TvContentRating |
No |
setReleaseDate(java.lang.String releaseDate) setReleaseDate(java.util.Date releaseDate) |
Sets the Content release year. | No |
setReviewRating(java.lang.String reviewRating) |
Customer rating, possible values range from 0 to 10. | No |
setIntentUri(Uri intentUri) |
Sets the intent URI which is launched when the recommendation is selected. | No |
setPosterArtUri(Uri posterArtUri) |
Sets the background image URL for the recommendation. | No |
setStartTimeUtcMillis(long startTime) |
Used to set the running time (when applicable) for the content. | No |
setEndTimeUtcMillis(long endTime) |
Used to set the running time (when applicable) for the content. | No |
setBackgroundImageUri()
is not supported.Amazon Enhancements to Recommendations
The following table lists extras that you can add to your notification objects.
The following table lists extras that you can add to your PreviewProgram
object.
Extra name | Data type | Details |
---|---|---|
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. |
com.amazon.extra.ACTION_OPTION |
int | Determines the context menu options displayed for each recommendation. One context menu action is supported and 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_OPTION are as follows:1: Watch with <App name> 2: Watch 3: Resume with <App name> 4: Resume 5: Switch <App name> Profile6: Change <App name> Settings7: Change Settings 8: View with <App name> 9: View 10: Play with <App name> 11: Play 12: Listen with <App name> 13: Listen If no value is provided, the default action will be Open and below that, Launch <App name> . |
com.amazon.extra.CONTENT_CAPTION_AVAILABILITY |
int | Caption availability of content:0 : Caption not available for content.1 : Caption available for content. |
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:
- Specifying Your App's Installation Location
- App install location
- android:installLocation manifest attribute
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: Nov 15, 2024