步骤3: 集成Alexa客户端库 (VSK Fire TV)
要将Alexa集成到您的应用中,您将需要集成Alexa客户端库。Alexa客户端库允许您的应用与Alexa通信并处理针对您的应用的Video Skill API指令。
该示例应用已经集成了Alexa客户端库版本1.4.6。(Project [项目] 窗格显示一个“AlexaClientLib”模块。) 如果Alexa客户端库已迭代到更高版本,则可以在Fire TV应用中更新Alexa客户端库。您还可以在示例应用中浏览
MainActivity.java
和VSKFireTVMessageHandler.java
文件,以了解如何集成和初始化Alexa客户端库。否则,请继续执行下一步,即步骤4: 集成Amazon Device Messaging (ADM)。- 下载Alexa客户端库
- 关于Alexa客户端库
- 在Fire TV应用中更新Alexa客户端库
- 将Alexa客户端库添加到您的Fire TV应用
- 配置Proguard
- 从您的应用的onCreate初始化Alexa客户端库
- 后续步骤
下载Alexa客户端库
您可以在此处下载Alexa客户端库:
请注意,一旦下载Alexa客户端库,即表示您同意亚马逊的程序材料许可协议(只提供英文版)。
有关版本的更多详细信息,请参阅Alexa客户端库发行说明。
关于Alexa客户端库
Alexa客户端库让您可以执行以下操作:
- 使用适用于Android的Login with Amazon (LWA) 进行亚马逊身份验证。
- 通过推断现有Echo与Fire TV之间的关系(而不是要求客户通过Alexa应用添加技能),自动将您的技能与Echo设备配对。
- 管理应用生命周期事件并将这些事件发回Alexa(这将帮助Alexa在用户与支持语音的Fire TV应用交互时做出更明智的决策)。
- 向应用中收到的指令发送Alexa响应。
有关详细说明Alexa客户端库的字段、方法和实现要求的Javadoc,请参阅Class AlexaClientManager。
在Fire TV应用中更新Alexa客户端库
要在Android Studio项目中更新现有版本的Alexa客户端库,请执行以下操作:
- 下载Alexa客户端库。下载文件后,将其解压缩。压缩文件夹包含一个名为
AlexaClientLib.aar
的文件。 - 在Android Studio中,右键单击AlexaClientLib模块,然后选择Reveal in Finder(在Finder中显示)(Mac) 或Show in Explorer(在资源管理器中显示)(Windows)。
- 打开AlexaClientLib文件夹。
- 拖入新的
AlexaClientLib.aar
文件,替换现有文件。当系统询问您是否要覆盖文件时,选择“Replace”(替换)。
将Alexa客户端库添加到您的Fire TV应用
要将Alexa客户端库 (AlexaClientLib.aar
) 添加到您的Android Studio项目中,请执行以下操作:
- 从上面的链接下载Alexa客户端库。下载文件后,将其解压缩。该压缩包包含一个名为
AlexaClientLib.aar
的文件和一些文档。 - 在您的Android Studio项目中,转到File(文件)> New(新建)> New Module(新建模块)。
- 选择Import .JAR/.AAR Package(导入.JAR/.AAR程序包),然后单击Next(下一步)。
- 在File name(文件名)字段中,选择
AlexaClientLib.aar
文件并单击Open(打开),然后单击Finish(完成)。 - 转到File(文件)> Project Structure(项目结构)。
- 在左侧菜单中的Modules(模块)下,选择app(应用)。
- 转到Dependencies(依赖项)选项卡。
- 如果您尚未在依赖项列表中看到AlexaClientLib,可单击底部的+按钮并选择3.模块依赖关系。
- 从列表中选择AlexaClientLib。
配置Proguard
如果您在Android项目中使用ProGuard,请进行以下更新:
- 找到您的proguard规则文件。
-
添加以下配置:
-libraryjars ../AlexaClientLib #保留LWA和Alexa客户端库类 -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.** { *; }
从您的应用的onCreate初始化Alexa客户端库
必须初始化Alexa客户端库,客户端库才能正常运行。在应用类中声明initializeAlexaClientLibrary()
。参考下面的代码示例。务必从onCreate()
调用initializeAlexaClientLibrary()
。
public class YourApplication extends Application {
@Override
protected void onCreate() {
super.onCreate();
// 先初始化Alexa客户端库
initializeAlexaClientLibrary();
// 初始化ADM
initializeAdm();
//(可选)启用VSK客户端库,以便VSK在后台立即开始自动配对,
// 这样便能让您的用户尽快使用语音服务。
// 您可以延迟此步骤,直到活跃用户登录您的应用。
AlexaClientManager.getSharedInstance().setAlexaEnabled(true);
}
private void initializeAlexaClient() {
// 检索AlexaClientManager的共享实例
AlexaClientManager clientManager = AlexaClientManager.getSharedInstance();
// 收集您的技能ID
final String alexaSkillId = "YOUR_SKILL_ID";
// 创建技能中支持的功能的列表
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() 初始化客户端库
clientManager.initialize(getApplicationContext(),
alexaSkillId,
AlexaClientManager.SKILL_STAGE_DEVELOPMENT,
capabilities);
}
private void initializeAdm() {
try {
final ADM adm = new ADM(this);
if (adm.isSupported()) {
if (adm.getRegistrationId() == null) {
// ADM现在还没准备好。您必须通过调用以下项来开始ADM注册:
// startRegister () API。当使用已注册的ADM id完成ADM注册时,
// ADM将在您的ADM处理程序服务上调用onRegister() API。
adm.startRegister();
} else {
//[重要]
// ADM下行信道已经可用。会遇到常见的情况,即
//应用程序重新启动。您的Fire TV上的ADM管理器会缓存之前的
// ADM注册信息,并在确定您的应用
// 已重新启动时立即提供它。
// 您必须将检索到的ADM注册ID提供给Alexa客户端库
final String admRegistrationId = adm.getRegistrationId();
Log.i("ADM registration Id:" + admRegistrationId);
// 提供获得的ADM注册ID
AlexaClientManager.getSharedInstance().setDownChannelReady(true, admRegistrationId);
}
}
} catch (Exception ex) {
Log.e(TAG, "ADM initialization is failed with exception", ex);
}
}
}
一般注意事项
-
技能阶段设置为
SKILL_STAGE_DEVELOPMENT
。在开发过程的后期,当您准备好发布应用时(在步骤12: 上线!中),可以将AlexaClientManager.SKILL_STAGE_DEVELOPMENT
更改为AlexaClientManager.SKILL_STAGE_LIVE
。 -
如果在调用初始化之前发生事件(例如,可见性变化,比如将应用置于后台/前台),则应用在强制停止并重新启动应用之前不会响应语音。
声明功能
上面的示例代码声明对以下功能的支持:
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将发送与此处列出的这些功能相关的指令。例如,如果您指明AlexaClientManager.CAPABILITY_CHANNEL_CONTROLLER
,则当用户说出“Change the channel to PBS”(将频道更改为PBS)时,Alexa将发送ChangeChannel
指令。 如果您没有声明该功能,Alexa将不会发送与该功能相关的指令。有关更多详细信息,请参阅Discover指令。
如果您的应用不支持特定功能,请在上面省略该功能。此外,如果您的应用支持这些API的功能,您可以添加AlexaClientManager.CAPABILITY_RECORD_CONTROLLER
和AlexaClientManager.CAPABILITY_KEYPAD_CONTROLLER
。下表描述了这些功能。
Alexa客户端库功能 | 指令能力 | 指令 |
---|---|---|
CAPABILITY_CHANNEL_CONTROLLER |
Alexa.ChannelController |
ChangeChannel |
CAPABILITY_REMOTE_VIDEO_PLAYER |
Alexa.RemoteVideoPlayer |
SearchAndDisplayResults SearchAndPlay |
CAPABILITY_PLAY_BACK_CONTROLLER |
Alexa.PlaybackController |
Pause Play Stop Resume Next Previous FastForward Rewind StartOver |
CAPABILITY_SEEK_CONTROLLER |
Alexa.SeekController |
AdjustSeekPosition |
CAPABILITY_KEYPAD_CONTROLLER |
Alexa.KeypadController |
SendKeystroke |
如果您希望在客户端库中声明没有预定义常量(例如List<String> capabilities
)的功能,则可以使用该功能的确切字符串名称来实现这点。例如,您可以按如下方式为GUI快捷方式添加“启动器”功能:capabilities.add(\"Alexa.Launcher\");
。
Discover
指令时,您的Lambda必须发回Discover.Response
以指明您的技能支持哪些功能。请参阅Discover
指令文档中的响应示例。自定义技能ID
在前面的代码中,将YOUR_SKILL_ID
替换为您自己的视频技能ID,即您之前在步骤1: 创建您的视频技能以及设置设备中复制的ID。
final String alexaSkillId = "YOUR_SKILL_ID";
用户登录或退出时启用或禁用Alexa客户端库
函数setAlexaEnabled()
用于由用户以可作为目标的终端节点形式,启用或禁用应用实例。建议您仅为已订阅的客户启用Alexa(设置为setAlexaEnabled(true)
)。(因此,代码中的内嵌注释会说明,您可以将此步骤延迟到活跃用户登录您的应用为止。) 请注意以下事项:
- 当用户登录您的应用时调用
setAlexaEnabled(true)
- 当用户注销时调用
setAlexaEnabled(false)
setAlexaEnabled
设置为false以响应用户的直接操作,但不响应自动事件,例如HDMI事件。当您的应用进入后台或终止时,请勿调用setAlexaEnabled(false)
。以下代码显示了一个示例:
public class YourSigninActivity extends Activity {
private void onUserSignedIn() {
// 用户登录时启用AlexaClient
AlexaClientManager.getSharedInstance().setAlexaEnabled(true);
}
private void onUserSignedOut() {
// 用户注销时禁用Alexa客户端
AlexaClientManager.getSharedInstance().setAlexaEnabled(false);
}
}
此规则的唯一例外是您的应用没有用户登录名 - 换句话说,无论用户是否登录或拥有特定的订阅,您的内容都可供用户使用。
构建下行信道服务
要接收来自Alexa服务的指令,您必须按照上面的示例参考代码在应用中构建下行信道服务。下行信道是主要用于向您的Fire TV应用提供云端启动指令的流。请注意以下有关下行信道服务的注意事项。
当您的下行信道服务准备就绪后,使用以下参数调用setDownChannelReady()
API:
- 第一个参数 (
isDownChannelReady
) 应为true
,以表示您的下行信道已准备就绪。 - 第二个参数 (
appInstanceId
) 应该是唯一标识您的应用实例的字符串。如果您使用Amazon Device Messaging (ADM),请对此参数使用应用的ADM注册ID。(如果您不想使用ADM,可以使用其他技术。)
当您的下行信道服务状态发生变化时,每次使用正确的状态标记值调用setDownChannelReady()
API。
在创建应用时初始化ADM服务 (initializeAdm();
),如下所示。前面的代码展示了ADM参考实现示例。
当您的下行信道准备就绪时,可提供应用实例ID。
public class YourADMHandler extends ADMMessageHandlerBase {
@Override
protected void onRegistered(final String registrationId) {
//[重要]
// ADM down channel is ready.使用获得的ADM注册Id将下行信道设置为就绪。
AlexaClientManager.getSharedInstance().setDownChannelReady(true, registrationId);
}
}
false
。关闭和打开此状态将导致Alexa取消注册并重新注册终端节点,这将对您的技能产生意想不到的后果。后续步骤
继续执行下一步: 步骤4: 集成Amazon Device Messaging (ADM)。
(如果遇到任何问题而无法继续,请参阅云端集成故障排除。)
Last updated: 2022年3月16日