手順6: アプリの動的機能を報告する
動的機能の統合により、ユーザーの状態(ログイン状態や定期購入のレベルなど)に応じてアプリの機能を提供できます。そのため、機能を報告するためにVSK Agentとの統合が必要になります。VSK Agentとの統合を行う方法として推奨されているのは、VSK Agent Client Libraryを使用する方法です。
サンプルアプリでは動的機能がレポートされるため、この手順でコーディングを行う必要はありません。詳細については、サンプルアプリの
DynamicCapabilityReporter
クラス、AndroidManifest.xml
、VSK Agent Client Library、機能ファイル(res/raw
にあります)を参照してください。- VSK Agentについて
- VSK Agentとの統合方法の選択
- オプション1の手順: VSK Agent Client Libraryを使用してVSK Agentサービスと統合する
- オプション2の手順: VSKApplicationAgentAPIパッケージを使用してVSK Agentと統合する
- ベストプラクティス: 動的機能の報告
- 次のステップ
VSK Agentについて
VSK Agentは、Fire OSのオンデバイスルーティングエージェントです。Fire TV対応アプリでは、VSKAgentClient
クラスを使用して、動的機能をVSK Agentにレポートします。これらの機能により、アプリにブロードキャストできるディレクティブの種類をVSK Agentに知らせることができます。VSK Agentは、Androidインターフェース定義言語(AIDL)APIを使用してFire OSとやり取りします。
VSK Agentは、アプリがサポート可能なディレクティブのみを送信します。たとえば、アプリでPlaybackController
インターフェースをサポートできることを明示していない場合、AlexaからはPlaybackController
ディレクティブは送信されません。
VSK Agentとの統合方法の選択
VSK Agentとの統合には、次の2つの方法があります。
オプション1: VSK Agent Client Library(推奨される方法)
Amazonが提供するVSK Agent Client Libraryを使用する方法が推奨されます。VSK Agent Client Libraryを使用すると、VSK Agentのすべての機能を利用できるだけでなく、Androidのプロセス間通信(IPC)の細部を部分的に簡素化することができます。VSK Agent Client Libraryを使用すると、Fire TVのVSK Agentとの統合のために大量のコードを記述する必要性が低下します。つまり、このサービスへの接続の処理が自動で行われるようになり、通常のJavaのメソッドで呼び出しができるようになります。
VSK Agent Client Libraryを使用すると、動的な機能の追加や削除をいつでも選択的に行うことができます。将来的にアプリのUIの状態やその他の動的な状態の更新を知らせる高度な方法をサポートする予定がある場合は、このオプションを選択する必要があります。アプリでVSKの機能を有効にするには、VSK Agent Client Libraryを利用してVSK Agentと統合するのが、最も簡単で時間のかからない方法です(VSK Agent Client Libraryを使用しても、常にサポートされる機能は、静的機能の統合を行うことにより静的リソースで宣言できることに注意してください)。
VSK Agentでは、アプリの機能を動的にレポートするためのメソッドが2つ用意されています。
AddOrUpdateCapabilities()
- サポートする機能を宣言するためのメソッドです。sendCapabilityTestDirective()
- 統合のテストを行うためのメソッドです。
実装の手順については、後述のオプション1の手順: VSK Agent Client Libraryを使用してVSK Agentサービスと統合するを参照してください。
オプション2: VSKApplicationAgentAPI
VSK Agentに接続するためのもう1つの方法は、サービス定義のみを使用して、この接続のコードを開発者自身で管理する方法です。VSK Agent Client Libraryは、内部でバインドされたサービスと通信します。開発者は必要に応じて、VSKApplicationAgentAPI
パッケージを使用して、この内部のサービスと統合することができます。
このVSKApplicationAgentAPI
パッケージには、このサービスとやり取りするために必要な.aidl
ファイル(Androidインターフェース定義ライブラリに含まれます)およびJavaクラスが含まれています。推奨されている方法ではありませんが、特定の状況においては、すべてのコードを開発者自身で管理した方が望ましい場合があることはAmazonでも認識しています。このような方法は、依存関係を排除するため、またはその他の要件があるために、プロジェクトでAmazonのライブラリやコードを使用したくない場合には好ましいと考えられます。
簡単な手順については、オプション2の手順: VSKApplicationAgentAPIパッケージを使用してVSK Agentと統合するを参照してください。VSKApplicationAgentAPI
パッケージの詳細な使用方法については、このドキュメントでは扱いません。
オプション1の手順: VSK Agent Client Libraryを使用してVSK Agentサービスと統合する
VSK Agent Client Libraryと統合してVSK Agentと通信する場合(上記オプション1)は、次の手順を実行します。
プロジェクトへのVSK Agent Client Libraryの追加
-
VSK Agent Client Library(AARファイル)をダウンロードします。
VSK Agent Client Libraryをダウンロードすると、Amazonのプログラム素材ライセンス契約に同意したものと見なされます。
(「VSK Agent Client Library」は、クラウド側の統合で使用される「Alexa Client Library」とは異なることに注意してください。)
-
VSK Agent Client Libraryをプロジェクトに追加します。Android Studioで、[File] > [New] > [Module] の順に選択します。[Import .JAR/.AAR Package] を選択し、VSKApplicationAgentClientLibraryファイルを選択します。
-
このAARファイルをインポートすると、Android StudioによりVSKApplicationAgentClientLibraryが
settings.gradle (Project Settings)
に追加され、アプリのbuild.gradle
ファイルで依存関係として追加できるようになります。[Gradle Scripts] を展開し、settings.gradle (Project Settings)
を開きます。次のように、VSKApplicationAgentClientLibrary
がインクルードされていることを確認します。include ':VSKApplicationAgentClientLibrary'
-
[Gradle Scripts] を展開し、
build.gradle (Module: App)
を開きます。次のように、VSKApplicationAgentClientLibrary
の依存関係をdependencies
オブジェクトに追加します。dependencies { implementation project(path: ':VSKApplicationAgentClientLibrary') }
VSK Agent Client Libraryは、MavenまたはJCenterでは使用できないことに注意してください。
サンプルアプリに関する注意事項
サンプルアプリでは、VSK Agent Client Libraryが組み込まれています。Android Studioで、[Project] ビューに切り替えて、VSKApplicationAgentClientLibrary
フォルダを確認してください。
マニフェストの構成
アプリのマニフェスト(AndroidManifest.xml
)には、アプリで実行されるアクティビティの宣言が記述されます。アプリのマニフェストで、次のようにパーミッションを追加して、アプリでVSK Agentとの統合ができるようにします。
<uses-permission android:name="com.amazon.alexa.vsk_app_agent_api.permission.BIND_SERVICE_PERMISSION" />
アプリのマニフェストの例については、サンプルアプリの
AndroidManifest.xml
ファイル(app/manifests
にあります)を参照してください。VSK Agent Client Libraryの初期化
次の手順は、コードベース内でVSK Agent Client Libraryを初期化することです。
サンプルアプリでは、この初期化は
DynamicCapabilityReporter
クラスで実行されます(src/java/com/example/vskfiretv/reporter
を参照してください)。DynamicCapabilityReporter
は、アプリでサポートする音声機能を報告するクラスです。-
VSK Agentクライアントの新しいインスタンスを作成します。
public DynamicCapabilityReporter(final Context context) { this.context = context; // VSKAgentClientのインスタンスを作成します client = new VSKAgentClient(context); }
-
reportDynamicCapabilities()
メソッドで機能を宣言し、AddOrUpdateCapabilities()
メソッドを使用して機能レポートのリクエストを行います。アプリでは、ユーザーのログイン後にこのメソッドを呼び出します。public void reportDynamicCapabilities() { // アプリでサポートする機能のリストを作成します。 final List<AlexaCapability> supportedCapabilities = new ArrayList<>(); supportedCapabilities.add(getAlexaCapability(R.raw.remote_video_player_capability)); // RemoteVideoPlayer機能 // supportedCapabilities.add(getAlexaCapability(R.raw.play_back_controller_capability)); // PlaybackController機能 -- PlaybackControllerよりもMedia Sessionが推奨されているため、ここではコメントアウト //supportedCapabilities.add(getAlexaCapability(R.raw.channel_controller_capability)); // ChannelController機能(アプリのみの統合では未サポート) //supportedCapabilities.add(getAlexaCapability(R.raw.seek_controller_capability)); // SeekController機能 //supportedCapabilities.add(getAlexaCapability(R.raw.keypad_controller_capability)); // KeypadController機能(アプリのみの統合では未サポート) // 機能レポートのリクエストを実行します final AddOrUpdateCapabilitiesRequest request = new AddOrUpdateCapabilitiesRequest(supportedCapabilities); }
注: 上記のコードでは多くの機能がコメントアウトされています。それらは、Fire TV対応の実装では推奨されていない機能であるためです。RemoteVideoPlayer
のみが、Fire TV対応アプリのVSK統合で推奨される機能となっています(非推奨のインターフェースには、ケーブルテレビ用セットトップボックスなど、Fire TV以外のVSK統合に関連するものなどがあります)。Alexaは、ここに記載されている機能に関連するディレクティブを送信します。たとえば、
remote_video_player_capability
を指定した場合、AlexaはRemoteVideoPlayer
インターフェースに関連するディレクティブを送信します。機能を宣言していないと、Alexaは、その機能に関連するディレクティブを送信しません。 -
前述のコードでは、
Utils.getTextForRawResource(R.raw.remote_video_player)
のようにコードでファイルを参照することにより、機能を宣言しています。上記のサンプルコード内の参照は、次のようになっています。remote_video_player_capability
(RemoteVideoPlayer
を参照)seek_controller_capability
(SeekController
を参照)play_back_controller_capability
(PlaybackController
を参照)keypad_controller
(KeypadController
を参照)channel_controller_capability
(ChannelController
を参照)
アプリでサポートするインターフェースに応じて、
app/res/raw
に必要なファイルを作成し、これらの名前を付け、機能を宣言します。各機能のJSONオブジェクトの詳細については、アプリのみの統合でサポートされる機能を参照してください。サンプルアプリに関する注意事項
サンプルアプリのapp/res/raw
でこれらの機能を確認できます。必要に応じて、これらのサンプルのJSONオブジェクトを、開発するアプリにコピーすることができます。 -
addOrUpdateCapabilities()
メソッドを使用して、アプリの動的機能をVSK Agentにレポートします。Log.i(TAG, "動的機能をVSK Agentにレポートしています..."); final boolean reportingStatus = client.addOrUpdateCapabilities(request); if(reportingStatus) { Log.i(TAG, "動的機能をVSK Agentに正常にレポートしました"); return; } Log.e(TAG, "動的機能をVSK Agentにレポートできませんでした"); }
これで、アプリがこれらの機能をサポートしていることが、VSK Agentで認識されます。後でFire TVでアプリを実行し、ログを確認すると(手順10: 発話をテストしてログを確認する)、
DynamicCapabilityReporter
クラスで、これらの機能がVSK Agentにレポートされていることを確認できます。今後の予定: ユーザーの状態に応じたさまざまなカタログの指定
将来的に、必要な場合は、ユーザーの定期購入や状態に応じてそれぞれ異なるカタログを指定できるようになります。たとえば、1つのカタログID(例:acme_free
)では無料コンテンツを提供し、別のカタログ(例:acme_premium
)では有料コンテンツを提供することができます。これを実現するには、ユーザーの状態に応じて、異なる機能を報告します。
たとえば、プレミアムレベルの定期購入をしているユーザーの場合は、機能ファイルで別のcatalogs
プロパティを指定して機能を報告することができます。これらのユーザー用には、acme_premium
が指定された機能ファイルを使用することができます。ログインしていないユーザー用には、catalogsプロパティにacme_free
を指定した機能ファイルを使用します。catalogs
プロパティの詳細については、「アプリのみの統合でサポートされる機能」のRemoteVideoPlayer機能を参照してください。この機能は将来サポート予定であり、現時点ではサポートされていないことに注意してください。
動的機能を報告するためのコード例(全文)
動的機能を報告するためのコード例の全文を以下に示します。
// -------------------------------\
// MyApplication.java
// -------------------------------/
public class MyApplication extends Application {
private static MyApplication sTheApp;
private VSKAgentClient client;
private HandlerThread vskAgentThread;
private Handler vskAgentHandler;...
public static MyApplication getInstance() {
return sTheApp;
}
@Override
public void onCreate() {
super.onCreate();
//...
vskAgentThread = new HandlerThread("VSKAgentThread");
vskAgentThread.start()
vskAgentHandler = new Handler(vskAgentThread.getLooper);
client = new VSKAgentClient(this);
reportCapabilities();
//...
}
//...
public void reportCapabilities() {
// API呼び出しはバックグラウンドスレッドで実行する必要があります
vskAgentHandler.post(new Runnable() {
public void run() {
reportCapabilitiesInternal()
}
});
}
private void reportCapabilitiesInternal() {
// 現在のアプリの状態を基に、現在サポートされている
// Alexaの機能を判断します。機能のJSONを動的に構築するか、
// リソースファイルのJSONを参照することができます(ここでは後者)。
List < AlexaCapability > supportedCapabilities = new ArrayList < >();
if (accountManager.isLoggedIn()) supportedCapabilities.add(new AlexaCapability(Utils.getTextForRawResource(R.raw.remote_video_player)));
//supportedCapabilities.add(new AlexaCapability(Utils.getTextForRawResource(R.raw.playback_controller)));
if (accountManager.geteCurrentCustomer().hasSubscription(Subscription.LIVE_TV) {
supportedCapabilities.add(new AlexaCapability(Utils.getTextForRawResource(R.raw.channel_controller)));
}
}
AddOrUpdateCapabilitiesRequest request = new AddOrUpdateCapabilitiesRequest(supportedCapabilities);
boolean success = client.addOrUpdateCapabilities(request);
if (!success) {
// エラー処理
}
}
private String getTextForRawResource(int resId) {
InputStream inputStream = getResources().openRawResource(resId);
String line;
StringBuilder result = new StringBuilder();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
while ((line = reader.readLine()) != null) {
result.append(line).append('\n');
}
return result.toString();
} catch(IOException e) {
// エラー
}
return null;
}
VSKAgentClient
クラスはメインスレッドから呼び出す必要があり、そうでない場合は例外がスローされます。一般に、動的機能は、アプリの開始時と機能の変更時に報告する必要があります。次のステップに進む前に、以下で説明するベストプラクティスを必ず確認してください。オプション2の手順: VSKApplicationAgentAPIパッケージを使用してVSK Agentと統合する
VSKApplicationAgentAPI
パッケージを使用してVSK Agentとの統合を行う(VSK Agent Client Libraryを使用しない)場合は、以下の手順を実行します。
-
VSKApplicationAgentAPI(AARファイル)をダウンロードします。
VSKApplicationAgentAPIをダウンロードすると、Amazonのプログラム素材ライセンス契約に同意したものと見なされます。
-
VSKApplicationAgentAPIをプロジェクトに追加します。Android Studioで、[File] > [New] > [Module] の順に選択します。[Import .JAR/.AAR Package] を選択し、VSKApplicationAgentAPIファイルを選択します。
-
このAARファイルをインポートすると、Android Studioによりファイルが
settings.gradle (Project Settings)
に追加され、アプリのbuild.gradle
ファイルで依存関係として追加できるようになります。[Gradle Scripts] を展開し、settings.gradle (Project Settings)
ファイルを開きます。次のように、VSKApplicationAgentAPI
がインクルードされていることを確認します。include ':VSKApplicationAgentAPI'
-
[Gradle Scripts] を展開し、
build.gradle (Module: App)
を開きます。次のように、VSKApplicationAgentAPI
の依存関係をdependencies
オブジェクトに追加します。dependencies { implementation project(path: ':VSKApplicationAgentAPI') }
- アプリのマニフェストで必要なパーミッションを宣言します。
- アプリの作成時に、
addOrUpdateCapabilities()
メソッドを使用して、現在サポートされている機能を報告します。 - アプリの状態が変化したことでサポートされる機能に変更が生じる場合も、そのつど
addOrUpdateCapabilities()
を呼び出します。
ベストプラクティス: 動的機能の報告
動的機能をAlexa App Agentに報告すると、エージェントは、前回の報告以降にアプリの機能が変更されたかどうかを判断し、変更があればAlexaクラウドに報告します。このため、アプリが開始されるたびに動的機能を報告することをお勧めします。ただし、報告間でこれらの機能が変わることは望ましくありません。動的機能の変更は、アプリまたはユーザーの状態に長期的な変化があり、ユーザーのリクエストを処理する能力に影響が及ぶ場合に報告されるべきものです。
たとえば、ユーザーがアプリからログアウトしたら、コンテンツを再生する機能を削除できます。動的機能の変更を報告すると、Alexaに報告される機能が不必要に変更され、ユーザーに影響を与える可能性があります。これは特に、大量の探索トラフィックが原因でアプリがスロットリングされている場合に当てはまります。これを避けるために、動的機能を報告するときは以下のガイドラインに従うことを強くお勧めします。
- 未知の状態に基づいて機能を報告しないでください。たとえば、ユーザーのログイン状態に依存する動的機能をアプリで報告する場合、ログイン状態が非同期で決定されるのであれば、その状態が判明するまで待ってから報告します。ユーザーがログアウトしたかのように先に動的機能を報告して、その少し後に再び報告するようなことは避けてください。
- 頻繁に変更される可能性のある一時的な状態に基づいて機能を報告しないでください。たとえば、コンテンツが再生されているかどうかに基づいて
PlaybackController
やSeekController
を追加または削除する必要はありません。機能インターフェースで宣言されているアクションにアプリが対応していれば十分です。 - アプリロジック外の状態に基づいて機能を追加したり削除したりしないでください。たとえば、アプリがフォアグラウンドにあるかどうかや、ユーザーがFire TVで入力を切り替えたかどうかに基づいてアプリの機能を変更する必要はありません。
次のステップ
次の 手順7: BroadcastReceiverを追加するに進みます。