Step 3: Integrate the Alexa Client Library (VSK Fire TV)

To integrate Alexa into your app, you will need to integrate the Alexa Client Library. The Alexa Client Library allows your application to communicate with Alexa and handle Video Skill API directives intended for your application.

Sample App Instructions

If you're working with the sample Fire TV app, the sample app already has the Alexa Client Library integrated. You can skip to the next step: Step 4: Integrate Amazon Device Messaging (ADM). Or if desired, skip down to Exploring the Configuration in the Sample App for details on viewing the configuration.

About the Alexa Client Library

This Alexa Client Library allows you to do the following:

  • Authenticate with Amazon using Login with Amazon (LWA) for Android.
  • Automatically pair your skill with an Echo device by inferring a relationship from an existing Echo to Fire TV (rather than requiring a customer to add the skill through the Alexa App).
  • Manage application lifecycle events and send those events back to Alexa (which will help Alexa make more intelligent decisions when users interact with voice-enabled Fire TV apps).
  • Send Alexa responses to directives received in your application.

Javadoc for Alexa Client Library

For a Javadoc detailing the fields, methods, and implementation requirements for the Alexa Client Library, see Class AlexaClientManager. The following sections guide you through the implementation described in this Javadoc.

Add the Alexa Client Library to your Fire TV App

If you are using Gradle with Android Studio, you can integrate Alexa Video Skill Client Library using the Android Archive (AAR) file contained in the released SDK. To add the Alexa Video Skill Client Library (AlexaClientLib.aar) into your project in Android Studio, do the following:

  1. Download the Alexa Client Library. After downloading the file, unzip it. The zip contains a file called AlexaClientLib.aar.
  2. In your Android Studio project, go to File > New > New Module.
  3. Select Import .JAR/.AAR Package and click Next.
  4. In the File name field, select the AlexaClientLib.aar file and click Open, and then click Finish.
  5. Go to File > Project Structure.
  6. Under Modules in the left menu, select app.
  7. Go to Dependencies tab.
  8. If you don't already see AlexaClientLib in the list of dependencies, click the + button in the bottom and select 3. Module dependency.
  9. Select the AlexaClientLib from the list.

Configure Proguard

If you're using ProGuard in your Android project, make the following update:

  1. Locate your proguard rules file.
  2. Add the following configuration:

    -libraryjars ../AlexaClientLib
    
    # Keep the LWA and Alexa Client Library classes
    -dontwarn com.amazon.identity.auth.device.**
    -dontwarn com.amazon.alexa.vsk.clientlib.**
    
    -keep class com.amazon.identity.auth.device.** { *; }
    -keep class com.amazon.alexa.vsk.clientlib.** { *; }
    

Initialize the Alexa Client Library from Your App's onCreate

The Alexa Client Library must be initialized for the client library to work correctly.

Declare initializeAlexaClientLibrary() in your Application class. Reference the code sample below. Make sure to call initializeAlexaClientLibrary() from onCreate().

public class YourApplication extends Application {
    @Override
    protected void onCreate() {
        super.onCreate();

        // [IMPORTANT]
        // initialize the VSK client library.
        initializeAlexaClient();

        ...
    }

    private void initializeAlexaClient() {
        // Retrieve the shared instance of the AlexaClientManager
        AlexaClientManager clientManager = AlexaClientManager.getSharedInstance();

        // Gather your Skill ID
        final String alexaSkillId = "YOUR_SKILL_ID";

        // Create a list of supported capabilities in your skill.
        List capabilities = new ArrayList<>();
        capabilities.add(AlexaClientManager.CAPABILITY_CHANNEL_CONTROLLER);
        capabilities.add(AlexaClientManager.CAPABILITY_PLAY_BACK_CONTROLLER);
        capabilities.add(AlexaClientManager.CAPABILITY_REMOTE_VIDEO_PLAYER);
        capabilities.add(AlexaClientManager.CAPABILITY_SEEK_CONTROLLER);

        // Initialize the client library by calling initialize().
        clientManager.initialize(getApplicationContext(),
                alexaSkillId,
                AlexaClientManager.SKILL_STAGE_DEVELOPMENT,
                capabilities);

       // (Optional) Enable the VSK client library so that VSK start auto-pairing in background
       // immediately which will enable your user use Voice service ASAP.
       // You can delay this step until active user signed-in to your application.
       clientManager.setAlexaEnabled(true);
    }
}

Note the following about the above code:

  • It's recommended that you enable Alexa (setting clientManager.setAlexaEnabled(true);) only for subscribed customers. Hence the inline comment above that says you can delay this step until the active user signs in to your application.

  • The skill stage is set to SKILL_STAGE_DEVELOPMENT. Later in the development process, when you're ready to publish your app (in Step 12: Go Live!), you will change AlexaClientManager.SKILL_STAGE_DEVELOPMENT to AlexaClientManager.SKILL_STAGE_LIVE.

  • If an event (for example, a visibility change, such as backgrounding/foregrounding the app) occurs before initialize is called, the app will not respond to voice until the app is force-stopped and restarted.

Declaring Capabilities

The sample code above declares support for these capabilities:

capabilities.add(AlexaClientManager.CAPABILITY_CHANNEL_CONTROLLER);
capabilities.add(AlexaClientManager.CAPABILITY_REMOTE_VIDEO_PLAYER);
capabilities.add(AlexaClientManager.CAPABILITY_PLAY_BACK_CONTROLLER);
capabilities.add(AlexaClientManager.CAPABILITY_SEEK_CONTROLLER);

Alexa will send directives related to these capabilities listed here. For example, if you indicate CAPABILITY_CHANNEL_CONTROLLER, Alexa will send ChangeChannel directives when users say "Change the channel to PBS." If you don't have the capability declared, Alexa won't send directives related to the capability. For more detail, see the Discover Directives.

If your app doesn't support a particular capability, omit that capability from the above. Additionally, you can add AlexaClientManager.CAPABILITY_RECORD_CONTROLLER and AlexaClientManager.CAPABILITY_KEYPAD_CONTROLLER if your app supports the functionality of these APIs. The capabilities are described in the following table.

Client Library Capability Name Directive Capability Name
AlexaClientManager.CAPABILITY_CHANNEL_CONTROLLER Alexa.ChannelController
AlexaClientManager.CAPABILITY_REMOTE_VIDEO_PLAYER Alexa.RemoteVideoPlayer
AlexaClientManager.CAPABILITY_PLAY_BACK_CONTROLLER Alexa.PlaybackController
AlexaClientManager.CAPABILITY_SEEK_CONTROLLER Alexa.SeekController
AlexaClientManager.CAPABILITY_RECORD_CONTROLLER Alexa.RecordController
AlexaClientManager.CAPABILITY_KEYPAD_CONTROLLER Alexa.KeypadController

If you would like to declare a capability without a predefined constant (e.g., List<String> capabilities) in the client library, you can do so by using the exact string name of that capability. For example, you would add the "Launcher" capability for GUI shortcuts as follows: capabilities.add(\"Alexa.Launcher\");.

Customize the Skill ID

In the previous code, replace YOUR_SKILL_ID with your own Video Skill ID, which you copied earlier in Step 1: Create a Video Skill and Set Up Devices.

final String alexaSkillId = "YOUR_SKILL_ID";

Enable or Disable the Alexa Client Library When User Sign In or Out

The function setAlexaEnabled() is used to enable or disable an app instance as a targetable endpoint by the user. Do the following:

  • Call setAlexaEnabled(true) when the user logs into your app
  • Call setAlexaEnabled(false) when the user logs out.

The following code shows an example:

public class YourSigninActivity extends Activity {
    private void onUserSignedIn() {
        // Enable the AlexaClient when user sign-in.
        AlexaClientManager.getSharedInstance().setAlexaEnabled(true);
    }

    private void onUserSignedOut() {
        // Disable the Alexa Client when user signed-out.
        AlexaClientManager.getSharedInstance().setAlexaEnabled(false);
    }
}

The only exception to this rule is if your app does not have a user login — in other words, your content is available to users regardless of whether they're logged in or have a particular subscription.

Construct a Down-Channel Service

To receive directives from the Alexa Service, you must construct a down-channel service in your app as per the sample reference code below. The down-channel is a stream primarily used to deliver cloud-initiated directives to your Fire TV app. Note the following about the down-channel service.

When your down-channel service is ready, call the setDownChannelReady() API with parameters as follows:

  • The first parameter (isDownChannelReady) should be true to indicate that your down-channel is ready.
  • The second parameter (appInstanceId) should be a string that uniquely identifies your application instance. If you are using Amazon Device Messaging (ADM), use the app's ADM Registration ID for this parameter. (If you prefer not to use ADM, you can use another technology.)

When your down-channel service status changes, call the setDownChannelReady() API each time with the proper status flag value.

Initialize ADM service (initializeAdm();) at application creation time as shown below. The following code shows a sample ADM reference implementation:

public class YourApplication extends Application {

    @Override
    protected void onCreate() {
      super.onCreate();

      // Initialize the Alexa Client Library first.
      initializeAlexaClientLibrary();

      // Initialize ADM.
      initializeAdm();
    }

    private void initializeAdm() {
      try {
       final ADM adm = new ADM(this);
          if (adm.isSupported()) {
            if (adm.getRegistrationId() == null) {
              // ADM is not ready now. You have to start ADM registration by calling
              // startRegister() API. ADM will calls onRegister() API on your ADM
              // handler service when ADM registration was completed with registered ADM id.
              adm.startRegister();
            } else {
              // [IMPORTANT]
              // ADM down-channel is already available. This is a common case that your
              // application restarted. ADM manager on your Fire TV caches the previous
              // ADM registration info and provides it immediately when your application
              // is identified as restarted.
              //
              // You have to provide the retrieved ADM registration Id to the Alexa Client library.
              final String admRegistrationId = adm.getRegistrationId();
              Log.i(TAG, "ADM registration Id:" + admRegistrationId);

              // Provide the acquired ADM registration ID.
              final AlexaClientManager alexaClientManager = AlexaClientManager.getSharedInstance();
              alexaClientManager.setDownChannelReady(true, admRegistrationId);
           }
         }
       } catch (Exception ex) {
          Log.e(TAG, "ADM initialization is failed with exception", ex);
      }
   }
}

Provide the application instance ID when your down channel is ready.

  public class YourADMHandler extends ADMMessageHandlerBase {
      @Override
      protected void onRegistered(final String registrationId) {
          // [IMPORTANT]
          // ADM down channel is ready. Set the downchannel as ready with acquired ADM registration Id.
          final AlexaClientManager alexaClientManager = AlexaClientManager.getSharedInstance();
          alexaClientManager.setDownChannelReady(true, registrationId);
      }
  }

Exploring the Configuration in the Sample App

You can explore the sample app's integration a bit more, or continue on to the next step in the integration process. To see some of the above code that integrates and initializes the Alexa Client Library in the sample app, do the following:

  • Double-click the AlexaClientLib module name. Android Studio opens up the Project Structure dialog box with the Modules tab selected. Click the Dependencies tab and you will see the AlexaClientLib listed.
  • Press Shift twice and search for proguard to view the proguard-rules.pro file (inside AMZNMediaPlayerComponent).
  • Press Shift twice and search for TenFootApp.java (inside TVUIComponent). This code shows the initialization of the Alexa Client Library with initializeAlexaClientLibrary().
  • In the same TenFootApp.java file, look for the initialization of ADM with initializeAdm().

Next Steps

Continue on to the next step: Step 4: Integrate Amazon Device Messaging (ADM).

(If you run into any issues that prevent you from continuing, see Troubleshooting.)