雑談対話APIを使ったコンピュータとのチャットアプリ(1)
この雑談対話APIを使って、ユーザとコンピュータで雑談するアプリを作成します。まず、Eclipseを起動し、新規でAndroidプロジェクトを作成します。プロジェクト名は「BotChat」とし、エントリポイントとなるアクティビティをMainActivity.java、レイアウトファイルをactivity_main.xmlとして作成します。
画面の作成(ListViewとカスタムレイアウト作成)
最初にアプリケーションのUIを作成します。ユーザとコンピュータでの会話を交互に表示するため、ListViewコントロールを使います。ListViewコントロールは、複数のアイテムを1つにまとめてリスト形式で表示することができるビューです。
まず、プロジェクトで作成したactivity_main.xmlのレイアウトに対話内容を表示するためのListViewコントロールと、対話内容を送信するためのEditTextコントロールとButtonコントロールを配置します。
ListViewコントロールは、あらかじめいくつかのレイアウトが用意されていますが、今回は、ユーザとコンピュータの会話を異なるレイアウトで表示したいので、カスタムレイアウトを作成します。
まず、ユーザの会話を表示するためのレイアウトをcomment_list_right.xmlとして作成し、LinearLayoutコントロール内にTextViewコントロールとImageViewコントロールを水平方向に配置します。
同様に、画像とテキストビューを水平配置した、コンピュータからの返答を表示するためのレイアウトをcomment_list_left.xmlとして作成します。コードの詳細については、Androidプロジェクトのres/layout配下のサンプルを確認してください。
会話データの保持クラス作成
次に、カスタムレイアウト内で表示するデータを保持するためクラスであるCommentItem.javaを作成します。CommentItem.javaでは、コメントのテキストデータを保持するString型のフィールドと、表示する画像のリソースIDを保持するint型フィールドと表示するレイアウトのリソースIDを保持するint型フィールドをもたせます。これを他クラスから利用するため、各フィールドのアクセサメソッドを実装します。
Adapterクラスの作成
これで、画面(XMLレイアウト)の作成とデータ保持クラス(CommentItem.java)ができましたので、これらの橋渡しをするためのAdapterクラスを作成します。画面とデータの橋渡しを行うことをデータバインディングと言います。Adapterクラスを使うことで、データソースである雑談対話APIからの返答データと画面のデザインを分離することができます。
Androidでは次のようなAdapterがいくつか用意されています。
名前 | 説明 |
---|---|
ArrayAdapter | 配列やListを表示 |
SimpleAdapter | XMLファイルで定義された複数のビューを表示 |
CursorAdapter | データベースでアクセスするデータを表示 |
BaseAdapter | ArrayAdapter/SimpleAdapter/CursorAdapterの基底クラス |
Adapterは、ListViewコントロールだけでなく、AdapterViewから派生したViewで使えます。今回は、ユーザとコンピュータの会話を異なるレイアウトで交互に表示させたいので、ArrayAdapterを継承した独自のAdapterクラス(CommentAdapter.java)作成します。
public class CommentAdapter extends ArrayAdapter<CommentItem> { ~中略~ @Override public View getView(int pos, View convertView, ViewGroup parent) { CommentItem item = (CommentItem) getItem(pos); ViewHolder holder; // 1. Viewの再利用 if ( convertView == null || convertView.getId() != item.getLayoutType()) { convertView = inflater .inflate(item.getLayoutType(), parent, false); holder = new ViewHolder(convertView); convertView.setTag(holder); } else { // すでにViewがあればそれを使いまわす holder = (ViewHolder) convertView.getTag(); } // ビューにアイコンとコメントをセットする holder.icon.setImageResource(item.getImgtype()); holder.text.setText(item.getText()); return convertView; } // 2.ビューを保持するためのメンバークラス private static class ViewHolder { TextView text; ImageView icon; private ViewHolder(View view) { this.text = (TextView) view.findViewById(R.id.comment); this.icon = (ImageView) view.findViewById(R.id.image); } } }
getViewメソッドは、新しいデータが表示されるタイミングで呼び出されます。ListViewではスクロールして、画面外から新しいデータが表示されるタイミングです。1の箇所でパフォーマンスの観点からgetViewメソッド内でViewを再利用しています。
雑談対話APIのリクエスト
レイアウトおよびデータを保持/更新するクラスが作成できたので、次は、雑談対話APIの呼び出しを行います。
雑談対話APIでは、対話に必要な情報をリクエストパラメータとしてセットしてAPIを呼出し、サーバからのレスポンスに含まれる返答を取得することで雑談対話を行います。
流れは次のようになります。
リクエストパラメータは、DialogueRequestParamクラスを作成し、setUttメソッドの引数に、ユーザから入力された会話をセットし、API呼出しのリクエストを行います。
また、コンピュータと継続して雑談を行うためには、雑談対話APIのリクエストボディに、contextIDを設定します。このcontextIDとは、サーバのレスポンスに含まれる任意の値を、次回の会話のリクエストに設定することで、対話の流れや文脈をAPIエンジンが判断し、より自然な会話になるようにレスポンスを返します。
また、ユーザのプロフィール属性を設定することで、対話をよりユーザの好みに近づけることができます。設定できる主な属性は以下のとおりです。
内容 | 項目 | データ型 | 説明 |
---|---|---|---|
ニックネーム | nickname | string | ユーザのニックネーム |
性別 | sex | string | ユーザの性別を設定(男/女) |
血液型 | bloodtype | string | ユーザの血液型を設定(A/B/AB/O) |
年齢 | age | int | ユーザの年齢を設定 |
星座 | constellations | string | ユーザの星座を設定 |
場所 | place | string | ユーザの地域情報を設定(公式サイトの場所リスト参照) |
モード | mode | string | 対話のモード(対話:dialog/しりとり:srtr) |
キャラクタID | character | int | キャラクタを設定(なし: デフォルト/20: 関西弁/30: 赤ちゃん) |
このほかにも、誕生日やニックネームの読み方などのプロフィール属性も指定できます。詳細な仕様については、公式サイトや仕様書(PDF)を確認してください。
今回のチャットサンプルアプリではPreferenceActivityクラスを使って設定画面から登録しています。PreferenceActivityクラスの詳細については、本記事の内容からはそれますのでサンプルコードを参照してください。
雑談対話APIの呼び出しを行います。画面のコメント送信ボタンをクリックしたときの処理を次のように実装します。
public void onClick(View v) { // 1. 雑談対話パラメータ生成 DialogueRequestParam param = new DialogueRequestParam() { { // 設定値をリクエストパラメータに設定 sp = PreferenceManager .getDefaultSharedPreferences(getApplicationContext()); setUtt(editText.getText().toString()); ~中略~ setContext(contextId); } }; // 2. ユーザの発言を画面のListViewにセット String comment = editText.getText().toString(); CommentItem peopleData = new CommentItem(comment, R.drawable.people, R.layout.comment_list_right); list.add(peopleData); // 3. 雑談対話のタスク生成/実行 AlertDialog.Builder dlg = new AlertDialog.Builder( MainActivity.this); task = new DialogueAsyncTask(dlg); task.execute(param); }
簡単にコードの説明をします。
1. 雑談対話パラメータ生成
リクエストパラメータは、DialogueRequestParamクラスを作成し値をセットします。雑談対話APIで必須項目となるのが、会話内容です。setUttメソッドの引数に、ユーザから入力された会話をセットし、API呼出しのリクエストを行います。このutt属性は必須項目です。その他の項目は任意項目ですが、ContextIDをセットしないと会話が続きません。
2.ユーザの発言を画面のListViewにセット
ユーザの会話の入力値をListViewに表示します。
3. 雑談対話のタスク生成/実行
DialogueAsyncTaskクラスを生成し、雑談対話APIを実行します。executeメソッドに、1で生成したリクエストパラメータを引数として渡します。