Developer Console

Step 1: Integrate Your App with the Fire TV Launcher

Modifying your app to be used with Amazon Fire TV's launcher integrates your media content and your users' subscription statuses with other content in the Amazon Fire TV user interface. This process is also known as "deep linking" Amazon Fire TV's content to your content. After you integrate your app with the launcher, your content can be discovered and launched from catalog-integrated Amazon devices when users search for it. This page describes the required app changes to integrate your catalog with the Fire TV launcher.

Launcher integration overview

When customers start an app on Fire TV, the app sends an Android broadcast to the Fire TV launcher. The broadcast contains the class name of its own APK — for example, com.contentcompany.player — which is used with the deep link. When customers launch content from your app, Fire TV launches the class indicated in the broadcast and also passes in the LaunchId from the offer for the content as configured in the catalog.

In addition to including the class name in the broadcast, you send other metadata about the class that should be invoked by the launcher. You can include the following intents in the broadcast:

  • Sign-in intent
  • Playback intent

In addition to sending broadcast intents, your app must do the following to integrate with the Fire TV launcher:

  • Receive capability requests from the launcher and respond with the same information in the broadcast intent containing your app's capabilities.
  • Handle playback or sign-in requests from the launcher.
  • Handle errors when dealing with sync issues between your catalog and available content.
  • Provide the required filters, receivers, and permissions in the Android manifest.

Details for each of these tasks are listed in the sections that follow.

Note that your app is still responsible for:

  • Playback and sign-in activities and behavior.
  • Management of users' subscription status with your service.

Step A: Broadcast an intent from your app containing its capabilities

To play your content, the Fire TV launcher needs user information from your app to be able to later play your content or to request that the user sign in to your service. Your app must send this information as an Android broadcast intent at these times:

  • Each time your app starts up.
  • When the launcher requests it (see Step B: Receive capability requests from the launcher).
  • When your user's subscription status changes, for example, if they sign in to or out of your service.
  • When a user purchases, renews, or upgrades a subscription.

Types of intents: playback and sign-in intents

For Fire TV launcher integration and deep-linking, create two different types of Android intents that your app will need to broadcast:

Intent Description
Sign-in intent Broadcast a sign-in intent if the current user is not signed in to your app.
Playback intent Broadcast a playback intent if the current user is already signed in to your app, such as when a user has just signed in to or activates your app.

Use these two intent types to communicate your app's capabilities to Amazon Fire TV.

Building and sending an intent

To broadcast your app's capabilities, build a standard Android intent and send it to the app's context with the sendBroadcast() method. When you construct your intent:

  • Name the intent package com.amazon.tv.launcher.
  • Set the intent action to com.amazon.device.CAPABILITIES.
  • Specify all other intent information as intent extras.

The following example shows a sample broadcastCapabilities() method that broadcasts different intent extras based on a Boolean userIsSignedIn variable. All values in this example are sample data and must be replaced with your own values.

public void broadcastCapabilities(Context context)
{
    final Intent intent = new Intent();
    intent.setPackage("com.amazon.tv.launcher");
    intent.setAction("com.amazon.device.CAPABILITIES");
    if (userIsSignedIn) {
        // Playback intent extras
        intent.putExtra("amazon.intent.extra.PLAY_INTENT_ACTION","android.intent.action.VIEW");
        intent.putExtra("amazon.intent.extra.PLAY_INTENT_PACKAGE","com.contentcompany.player");
        intent.putExtra("amazon.intent.extra.PLAY_INTENT_CLASS","com.contentcompany.player.PlayActivity");
        intent.putExtra("amazon.intent.extra.PLAY_INTENT_FLAGS", Intent.FLAG_ACTIVITY_NEW_TASK | Intent.MORE_FLAGS);
    } else {
        // Sign-in intent extras
        intent.putExtra("amazon.intent.extra.SIGNIN_INTENT_ACTION","android.intent.action.VIEW");
        intent.putExtra("amazon.intent.extra.SIGNIN_INTENT_PACKAGE","com.contentcompany.player");
        intent.putExtra("amazon.intent.extra.SIGNIN_INTENT_CLASS","com.contentcompany.player.SignInActivity");
        intent.putExtra("amazon.intent.extra.SIGNIN_INTENT_FLAGS", Intent.FLAG_ACTIVITY_NEW_TASK | Intent.MORE_FLAGS);
    }
    
    intent.putExtra("amazon.intent.extra.DATA_EXTRA_NAME", "contentId");
    intent.putExtra("amazon.intent.extra.PARTNER_ID","contentcompany");

    // Send the broadcast to the launcher
    context.sendBroadcast(intent);
}

Intent extras

Specify the capabilities of your app in the keys and values of the extras field, using the Intent.putExtra() method. All of the intent extras have a prefix package of amazon.intent.extra.

The following table shows the required intent extras and the specific extras for playback and sign-in. All of the intent extra values are prefixed with amazon.intent.extra.

Intent extras When to use Description
PARTNER_ID Always Your Partner ID (supplied by Amazon) is the same ID that you use for catalog integration in the Partner field of your CDF file. Note that this ID is unique to your app, not to an individual or organization; if you or your organization has multiple Fire TV apps, each app will all have different Partner IDs.
DATA_EXTRA_NAME Conditional The name of the extra containing the content ID for your data, for example, titleData. Specify this value only if your content ID is not described by a URI. If your content ID is not in URI format (for example, 123456), use DATA_EXTRA_NAME to indicate the name of the intent extra the launcher should use for that ID. See Step C: Handling playback and sign-in intents from the launcher for more information. Access that content ID with the Intent.getStringExtra() method.
PLAY_INTENT_ACTION If user is signed in For playback intents, the intent action the launcher sends, usually android.intent.action.VIEW.
PLAY_INTENT_PACKAGE If user is signed in For playback intents, the package for your app, for example com.contentcompany.player.
PLAY_INTENT_CLASS If user is signed in For playback intents, the full package and class name of your app, for example, com.contentcompany.player.PlayActivity.
PLAY_INTENT_FLAGS If user is signed in For playback intents, any flags your app needs from the intent, as an integer. See the Android reference guide for Intent for possible flag values.
SIGNIN_INTENT_ACTION If user is signed out For sign-in intents, the intent action the launcher sends, usually android.intent.action.VIEW.
SIGNIN_INTENT_PACKAGE If user is signed out For sign-in intents, the package for your app, for example com.contentcompany.player.
SIGNIN_INTENT_CLASS If user is signed out For sign-in intents, the class name of your app, for example, SignInActivity.
SIGNIN_INTENT_FLAGS If user is signed out For sign-in intents, any flags your app needs from the intent, as an integer. See the Android reference guide for Intent for possible flag values.

One extra is always required:

  • Your Amazon-provided partner ID (PARTNER_ID). This is the same ID you use for catalog integration.

The remainder of the intent extras vary based on whether or not the user is authorized to play your content (they are signed in), or if they need to sign in before proceeding.

  • If the user is signed in, extras with the PLAY_ prefix are required.
  • If the user is not signed in, extras with the SIGNIN_ prefix are required.

Examples

For example, when a user signs in or activates your app, send an intent with the following extras:

  • PARTNER_ID
  • PLAY_INTENT_ACTION
  • PLAY_INTENT_PACKAGE
  • PLAY_INTENT_CLASS
  • PLAY_INTENT_FLAGS

In another example, if the launcher requests your app's capabilities, and the user is not signed in, send an intent with the following extras:

  • PARTNER_ID
  • SIGNIN_INTENT_ACTION
  • SIGNIN_INTENT_PACKAGE
  • SIGNIN_INTENT_CLASS
  • SIGNIN_INTENT_FLAGS

Do not provide both sets of intent extras at once; the launcher assumes that the existence of PLAY_ keys means that the user is authorized to view your content.

Step B: Receive capability requests from the launcher

Amazon Fire TV's launcher occasionally requests your app's capabilities and the subscription status of the user. The launcher requests this information with an Android broadcast intent, whose action is com.amazon.device.REQUEST_CAPABILITIES. Your app must respond to this request with the same intent that you previously created in Step A: Broadcast an intent from your app containing its capabilities.

The following example shows a simple class to handle the launcher's broadcast intent. The capability information you send to the launcher is the same information you send in Step A: Broadcast an intent from your app containing its capabilities, so you can use the same method (here, broadcastCapabilities()) to manage both those tasks.

public class CapabilityRequestReceiver extends BroadcastReceiver
{
   @Override public void onReceive(Context context, Intent intent)
   {
      broadcastCapabilities(); //the method you use to broadcast your app's information to the launcher
   }
}

Step C: Handling playback and sign-in intents from the launcher

When the user views the details for your content in the Fire TV user interface, Fire TV shows different options based on the user's status with your service:

  • If the user is logged into your service (you provided PLAY_ intent extras in the capabilities broadcast), a button labeled with the display name of your app appears (for example, "MyCompany Player"). If the user chooses that button, the launcher sends a playback intent to your app.
  • If the user is not logged in (you provided SIGNIN_ intent extras) a button labeled "Launch" with the display name of your app appears ("Launch MyCompany Player"). If the user chooses that button, the launcher sends a sign-in intent to your app.

In both cases, the launcher uses the information you provided in the capabilities broadcast to construct both playback and sign-in intents it sends your app.

To handle either playback or sign-in intents, implement an activity in your app to receive and handle those intents and to play the requested content.

This code shows the skeleton of a playback activity:

public class PlayActivity extends Activity {
   @Override
   public void onCreate(Bundle bundle) {
      super.onCreate(bundle);
      Uri data = getIntent().getData();
      //Play the content specified by 'data'
      // OR
      String data = getIntent.getStringExtra("titleExtra");
      //Play the content specified by the extra you indicated in DATA_EXTRA_NAME
   }
}

Both the playback and sign-in intents include the ID of the requested content to enable your app to play that content immediately (playback intents) or after the user signs in (sign-in). You specify the IDs and the ID format in your media catalog as part of catalog integration.

If your content ID is not in URI format (for example, 123456), the launcher sends that ID in the extra you specified in DATA_EXTRA_NAME as part of the capabilities broadcast. You can access that content ID with the Intent.getStringExtra() method.

If users press the Back button consecutively (usually 3 times if starting from a media playback scenario), the app should ultimately return users to the last location where the users entered the application. In this case, the Search Results in the launcher.

Step D: Add error-handling code to deal with sync issues between your catalog and available content

One common issue that many Fire TV-integrated apps face is the occasional issue of their catalogs becoming out-of-sync with the actual content that is available. If a user selects a content item via search or browse, and that items is not actually available to play, the user will be taken to a black screen with no clear way to navigate out. This experience can be very frustrating for users and reflect negatively on accessing your app through Fire TV.

This syncing issue can happen for several reasons:

  • You just uploaded a new catalog and it was successfully ingested in the window of a few hours before the actual content was available to play.
  • You rotated out some of your content, and an updated catalog reflecting these changes has not been uploaded/ingested yet.

To prevent users from encountering the black screen after selecting an unavailable piece of content, Amazon recommends implementing error-handling code in your app. This code should address the use case where a user tries to select unavailable content, provides a meaningful error message to the user, and re-directs them to an appropriate location. This type of graceful failure should lead to a more positive user experience for your customers.

Step E: Configure the Android manifest

Configure your Android manifest to handle broadcast intents from the launcher. Specifically, you'll need to add three things:

  • Add intent filters to handle playback and sign-in intents.
  • Add a receiver for the launcher's capabilities to request intent.
  • Add a permission to enable your intents to be sent with the right permissions.

Add intent filters for playback and sign-in

Add intent filters for your playback and sign-in activities to receive intents from the launcher. This example uses a playback activity named PlayActivity:

<activity
    android:name=".PlayActivity"
    android:label="Playback Activity">
    ...
    <intent-filter>
        <action android:name="com.contentcompany.player.PlayActivity">
        <category android:name="android.intent.category.DEFAULT">
    </intent-filter>
</activity>

Add a receiver for launcher requests

Add a receiver element to the manifest with the name of your BroadcastReceiver class, and an intent-filter for the action com.amazon.device.REQUEST_CAPABILITIES. In this example the receiver class is CapabilityRequestReceiver:

<receiver android:name="CapabilityRequestReceiver" >
    <intent-filter>
    <action android:name="com.amazon.device.REQUEST_CAPABILITIES" />
    </intent-filter>
</receiver>

Add permissions

Add a uses-permission element to your manifest to ensure that the launcher accepts your intents:

<uses-permission android:name="com.amazon.device.permission.COMRADE_CAPABILITIES" />

Step F: Test your launcher integration

Once you have integrated your app with Fire TV's launcher, you will need to validate your launcher integration before submitting your app to the Amazon Appstore:

See Step 2: Verify Deep Links from the Catalog for a flow of test cases to run through before submitting your app.

User experience (UX) guidelines for launcher integration

As you integrate with the launcher, keep this user experience in mind:

  • When a user selects content from your app via Fire TV's Universal Search and Browse results, begin playback of that content immediately; do not route the customer to your app or the work's detail screen before starting playback.
  • One exception to the previous point is the scenario where a user deeplinks into playback from a cold start, and the user has multiple profiles in your app. In this case, show the profile picker before starting playback. This practice can prevent the user from watching content in a different profile than they intended. For more information about deep link scenarios, see Test case: deep links.
  • As part of launcher integration, make sure that you publish your users' subscription status each time that your app opens or their subscription status changes so that the "Watch Now" option appears for current subscribers when your content is found from outside of your app. 
  • In the event that your currently available catalog becomes out-of-sync with your content that is actually available to users, implement error handling code to gracefully handle the use case where a user selects a content item that is not actually available for playback. If you do not implement error handling code for this scenario, the user will be taken to a black screen with no clear way to navigate back to Fire TV or your app or catalog, providing a confusing and negative user experience.

Launcher integration FAQ

Q: When a user selects an episode or series through browse or search, where should playback start from?
A: For a good user experience, playback should start by deep linking directly to the episode or series from the search or browse result. The user should not be routed to your app's home screen or anywhere else.
Q: When a user selects an episode or series, how immediately should playback begin?
A: Playback time can vary by app depending on buffering and other factors; however playback should begin directly after selection without any intermediate steps. Users should not be redirected to your app's home screen or elsewhere before beginning playback.
Q: When playback completes, where should the user land?
A: Users should land in the same place that they would expect to land if they had reached the content through your app as opposed to from an integrated catalog. For some apps, the next episode begins playing automatically. For other apps, users are taken to their personal recommendations. Just keep your user experience consistent whether they access your content through Fire TV or from within your app.

Next steps

After you finish integrating with the launcher, go to the next step: Step 2: Verify Deep Links from the Catalog.


Last updated: Sep 27, 2024