步骤7: 添加BroadcastReceiver(VSK Fire TV)
在清单中添加BroadcastReceiver时,Fire TV将通过Alexa指令将您应用的任何意图发送到您指定的BroadcastReceiver类,例如AlexaDirectiveReceiver
。在这个类中,您可以接受和处理Alexa发送到您应用的指令。
示例应用报告已拥有BroadcastReceiver,因此您无需在此步骤中进行任何编码。在示例应用中,BroadCastReceiver名为
AlexaDirectiveReceiver
(在java/com/example/vskfiretv/company/receiver
内)。在清单中声明BroadcastReceiver和意图筛选条件
Fire TV上的VSK Agent将根据您的应用将收到的意图发送指令。在您应用的清单中,声明一个带有意图筛选条件的BroadcastReceiver,用于处理来自VSK Agent的Alexa指令和其他功能报告。此BroadcastReceiver将在其意图筛选条件中处理ACTION_ALEXA_DIRECTIVE
和ACTION_REPORT_CAPABILITIES
。
在以下清单示例中,BroadcastReceiver的名称是AlexaDirectiveReceiver
,这就是示例应用中命名BroadcastReceiver的方式。可以将此名称更改为您在应用中需要的任何BroadcastReceiver名称。
<receiver
android:name=".receiver.AlexaDirectiveReceiver"
android:enabled="true"
android:exported="true"
android:permission="com.amazon.alexa.androidapplicationagent.permission.SEND_DATA">
<!--接收Alexa指令的意图操作-->
<intent-filter>
<action android:name="com.amazon.alexa.vsk_app_agent_api.ACTION_ALEXA_DIRECTIVE" />
</intent-filter>
<!--VSK Agent向应用请求的意图操作,用于报告其动态功能-->
<intent-filter>
<action android:name="com.amazon.alexa.vsk_app_agent_api.ACTION_REPORT_CAPABILITIES" />
</intent-filter>
</receiver>
有关如何声明BroadcastReceiver和意图筛选条件的示例,请参阅示例应用(在
app/src
内)中的AndroidManifest.xml
。添加BroadcastReceiver Java类
添加一个BroadcastReceiver Java类(例如AlexaDirectiveReceiver
),该类可以处理从VSK Agent发送的各种意图。您可以根据需要随意命名接收器,只要该类与您的清单声明(在上一部分中)相匹配。
BroadcastReceiver类负责处理Alexa收到的所有指令。Alexa向VSK Agent发送指令,然后VSK Agent将指令传达给您的BroadcastReceiver。
以下是BroadcastReceiver类的样板示例:
// -------------------------------\
// MyDirectiveReceiver.java
// -------------------------------/
public class MyDirectiveReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (VSKIntentConstants.ACTION_ALEXA_DIRECTIVE.equals(intent.getAction())) {
String namespace = intent.getStringExtra(VSKIntentConstants.EXTRA_DIRECTIVE_NAMESPACE);
String name = intent.getStringExtra(VSKIntentConstants.EXTRA_DIRECTIVE_NAME);
String payload = intent.getStringExtra(VSKIntentConstants.EXTRA_DIRECTIVE_PAYLOAD);
PendingIntent response = intent.getParcelableExtra(VSKIntentConstants.EXTRA_DIRECTIVE_RESPONSE_PENDING_INTENT);
boolean didSucceed = false;
boolean sendResponse = true;
if (namespace.equals("RemoteVideoPlayer") {
if (name.equals("SearchAndPlay") {
sendResponse = false; //该操作的处理是异步的,传递PendingIntent,并在我们知道该状态时进行回调
handlePlay(payload, response); //提取实体并构建意图以深层链接到播放器活动
} else if (name.equals("SearchAndDisplayResults") {
didSucceed = handleSearch(payload); //提取实体并构建意图以深层链接到搜索活动
}
} else if (name.equals("PlaybackController") {
// ...
} else if // ...
if (response != null && sendResponse) {
Intent success = new Intent().putExtra(VSKIntentConstants.EXTRA_DIRECTIVE_STATUS, didSucceed);
try {
response.send(context, 0, success);
} catch(PendingIntent.CanceledException e) {
//我们进行回复、记录错误可能花了太长时间
}
}
}
}
}
此代码接收来自Alexa的指令,并具有占位符,可以根据内容执行一些逻辑。如果成功处理了该指令,则您将发送一个状态为成功的响应。响应以true
或false
布尔值作为成功参数。
下一步为步骤8: 对指令做出反应,详细介绍了您的应用将收到的各种指令以及处理它们的方式。
与上面的样板示例相比,示例应用中的
AlexaDirectiveReceiver
类具有更详细的逻辑和其他环境。该示例应用尝试显示更多用于处理指令的实际环境信息。测试您的动态功能集成(可选)
通过动态集成(无论您是使用VSK Agent Client Library还是原始VSKApplicationAgentAPI程序包进行集成),您可以调用sendCapabilityTestDirective
方法来测试应用的集成。调用此方法会致使Fire OS路由代理回报用于将应用作为VSK指令调用的功能。
此方法不是为了测试任何特定的指令处理是否正常工作。其目的是验证设备通信通道是否正常运行,这样您就可以看到自己正确地报告了应用的功能,并且您的BroadcastReceiver可以从路由代理接收意图,而无需连接到Fire TV设备或创建请求/表述。
以下代码显示了如何调用sendCapabilityTestDirective()
方法。
// -------------------------------\
// MyDirectiveReceiver.java
// -------------------------------/
public class MyDirectiveReceiver extends BroadcastReciever {
@Override
public void onReceive(Context context, Intent intent) {
if (VSKIntentConstants.ACTION_ALEXA_DIRECTIVE.equals(intent.getAction())) {
String namespace = intent.getStringExtra(VSKIntentConstants.EXTRA_DIRECTIVE_NAMESPACE);
String name = intent.getStringExtra(VSKIntentConstants.EXTRA_DIRECTIVE_NAME);
String payload = intent.getStringExtra(VSKIntentConstants.EXTRA_DIRECTIVE_PAYLOAD);
if (VSKIntentConstants.TEST_DIRECTIVE_NAMESPACE.equals(namespace) &&
VSKIntentConstants.TEST_DIRECTIVE_NAME.equals(name)) {
log.d(TAG, payload);
}
...
}
...
}
}
requestTestDirectiveFromVSKAgent()
方法将触发VSK路由代理向您的应用发送测试指令的操作,无需向Alexa发出请求/表述。此意图的有效负载将是路由代理为您的应用记录在案的功能的JSON列表。例如:
{"capabilities":[{"configurations":{"operations":["SearchAndDisplayResults","SearchAndPlay"],"catalogs":[{"type":"VIDEO_PUBLIC_CATALOG_IDENTIFIER","sourceId":"imdb"}]},"interface":"Alexa.RemoteVideoPlayer","type":"AlexaInterface","version":"3.1"},{"interface":"Alexa.PlaybackController","type":"AlexaInterface","version":"3","supportedOperations":["Play","Pause","Stop"]}]}
示例应用注意事项
要查看示例应用中的sendCapabilityTestDirective()
方法, 请参看 DynamicCapabilityReporter
类(在 app/java/com/example/vskfiretv/company/reporter
内), 特别是以下部分:
public void requestTestDirectiveFromVSKAgent() {
Log.i(TAG, “请求VSK Agent将测试指令发送到应用”);
client.sendCapabilityTestDirective();
Log.i(TAG, "测试指令请求已完成");
}
示例应用在MainActivity.java
中调用此方法。示例应用使用ExecutorService
启动与主线程分开的后台线程:
//运行一个后台线程来报告功能
final ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.execute(reporter::reportDynamicCapabilities);
后续步骤
转到下一步: 步骤8: 对指令做出反应。