CodeZine(コードジン)

特集ページ一覧

誰でも手軽にNTTドコモのサービスのような機能を持つアプリが作れる ~ぼっちでも雑談を楽しめるAndroidアプリを作ろう

スマホアプリを豊かにする「docomo Developer support」で遊ぼう(4)

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2015/03/16 14:00

 「docomo Developer support」というサイトをご存じでしょうか。このサイトは、NTTドコモが公開している開発者向けのAPI提供サイトです。ここで公開されているAPIを使えば、NTTドコモのサービス「しゃべってコンシェル」などのような機能を、自作のアプリから簡単に利用できるようになります。みなさんも、公開されているAPIやSDKを使って、楽しいAndroidアプリを作ってみませんか。

はじめに

 第4回目の本稿は、「docomo Developer support」で公開されているAPIのなかで、「雑談対話API」をつかって、コンピュータと自然な会話を行うためのAndroidアプリ作ります(本稿は、2015年2月24日時点の最新情報に基づいております)。

チャットサンプルアプリの実行例
チャットサンプルアプリの実行例

対象読者

  • JavaとEclipseを用いたAndroidアプリの開発で、基本的な知識がある方
  • SNSで友達と楽しく会話したいが、筆者のように友達がいない方

雑談対話APIとは?

 NTTドコモが提供する雑談対話APIは、ユーザの会話を受け、その入力に対して自然な会話となる返事を提供するAPIです。このAPIを使うと、ユーザのどんな発話に対しても必ず返事を返しますので、コンピュータ相手にたわいもない雑談をすることができます。

雑談対話API
雑談対話API

 雑談対話APIは次の機能を持っています。

対話履歴機能

 ユーザとシステムの対話での話題と文脈を認識したうえで、大規模発話データをもとに返答をするので、ユーザの幅広い発言に柔軟に対応できます。

ユーザープロフィール認識機能

 ユーザのニックネーム/性別/誕生日などのプロフィール情報に基づいた会話をするため、より人間との対話に近い自然なやりとりができます。

パーソナライズ機能

 ContextIDと呼ばれる任意のキーを使って、コンピュータとの会話の流れを記憶し、個人の嗜好に基づいた対話を行うことができます。また、docomo IDと連携することで、ユーザごとの会話の内容をサーバ上に保存し、後日会話を行ったときもスムーズな内容になるよう学習します。このdocomo IDは、NTTドコモと回線契約のないユーザも無料で取得できます。

キャラクタ設定機能

 次の3タイプのキャラクタ(デフォルト/関西弁/赤ちゃん)から対話を楽しみたい相手を選ぶことができます。

しりとり機能

 ユーザとコンピュータのあいだでしりとりができます。単語の末尾から次の単語を選び返事をするので、しりとりゲームを行うことができます。しりとりではコンピュータが負けることもあります。語尾に「ん」がついたら負けを判定する機能もあります。

SDKの説明とAPI Keyの取得

 雑談対話APIのSDKは、公式ページからダウンロードできます。

SDKのダウンロードページ
SDKのダウンロードページ

 提供されているファイル(執筆時点では、Dialogue_API_Android_SDK_v2.0.0.zip)には、ライブラリ本体に、サンプルアプリ、利用ガイドなどが含まれています。利用ガイド(雑談対話SDK for Android利用ガイド_v2.0.0.pdf)には、SDKの使い方が詳しく載っていますので、参考にしてください。SDKで提供されるライブラリファイルは、次のとおりです。

SDKに含まれるライブラリファイル
ファイル名 ライブラリ概要
docomo-common-android-sdk-1.0.2.jar SDK共通ライブラリ
docomo-dialogue-android-sdk-2.0.0.jar 雑談対話ライブラリ
jackson-annotations-2.2.3.jar Jacksonライブラリ
jackson-core-2.2.3.jar Jacksonライブラリ
jackson-databind-2.2.3.jar Jacksonライブラリ

 雑談対話APIでは、ユーザからのリクエストおよびコンピュータからのレスポンスをJSONで返します。そのため、JSONデータを扱うためのオープンソースライブラリである、Jacksonライブラリが含まれています。Androidアプリで、雑談対話APIを利用するときはAndoridプロジェクトのlibsフォルダ内にこの5つのjarファイルをコピーしてください。SDKにはサンプルコードも同梱されています。

 雑談対話APIの実行に必要な、API Keyの取得手順については、連載初回の記事を参照してください。

雑談対話APIを使ったコンピュータとのチャットアプリ(1)

 この雑談対話APIを使って、ユーザとコンピュータで雑談するアプリを作成します。まず、Eclipseを起動し、新規でAndroidプロジェクトを作成します。プロジェクト名は「BotChat」とし、エントリポイントとなるアクティビティをMainActivity.java、レイアウトファイルをactivity_main.xmlとして作成します。

画面の作成(ListViewとカスタムレイアウト作成)

 最初にアプリケーションのUIを作成します。ユーザとコンピュータでの会話を交互に表示するため、ListViewコントロールを使います。ListViewコントロールは、複数のアイテムを1つにまとめてリスト形式で表示することができるビューです。

 まず、プロジェクトで作成したactivity_main.xmlのレイアウトに対話内容を表示するためのListViewコントロールと、対話内容を送信するためのEditTextコントロールとButtonコントロールを配置します。

 ListViewコントロールは、あらかじめいくつかのレイアウトが用意されていますが、今回は、ユーザとコンピュータの会話を異なるレイアウトで表示したいので、カスタムレイアウトを作成します。

ListViewコントロールに表示するレイアウト作成
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からの返答データと画面のデザインを分離することができます。

Adapterクラス
Adapterクラス

 Androidでは次のようなAdapterがいくつか用意されています。

Adapterクラス
名前 説明
ArrayAdapter 配列やListを表示
SimpleAdapter XMLファイルで定義された複数のビューを表示
CursorAdapter データベースでアクセスするデータを表示
BaseAdapter ArrayAdapter/SimpleAdapter/CursorAdapterの基底クラス

 Adapterは、ListViewコントロールだけでなく、AdapterViewから派生したViewで使えます。今回は、ユーザとコンピュータの会話を異なるレイアウトで交互に表示させたいので、ArrayAdapterを継承した独自のAdapterクラス(CommentAdapter.java)作成します。

リスト1 アダプタクラスの作成(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を呼出し、サーバからのレスポンスに含まれる返答を取得することで雑談対話を行います。

 流れは次のようになります。

雑談対話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の呼び出しを行います。画面のコメント送信ボタンをクリックしたときの処理を次のように実装します。

リスト2 リクエストパラメータとAPIの呼び出し(MainActivity.javaの抜粋)
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で生成したリクエストパラメータを引数として渡します。

雑談対話APIを使ったコンピュータとのチャットアプリ(2)

docomo IDと連携したパーソナライズ機能

 ContextIDを使ってユーザとコンピュータ間でより自然な対話になるよう文脈を解析しながらやりとりができますが、このContextIDはアプリケーションを終了すると、サーバ上から削除されてしまいます。雑談対話APIでは、会話の内容をdocomo IDと紐づけてサーバ上に蓄積し、後日改めて対話を行ったときも、前回の会話内容を分析し、より最適な会話を続けるパーソナライズ機能が提供されています。

 docomo IDを使ったパーソナライズを行うには、OAuth認証を行って、アクセストークンを取得します。取得したアクセストークンを、雑談対話APIのリクエストパラメータにセットすることで、docomo IDに紐づいた対話内容がサーバ上に蓄積されます。OAuth認証を行うためのSDKは以下のサイトから取得します。

 ダウンロードしたファイルに含まれるdocomo-oauth-android-sdk-1.1.1.jarをAndoridプロジェクトのlibsフォルダ内にコピーしてください。

 また、このSDKを利用するため、docomo Developer supportのマイページから必要なキー情報を取得します。

OAuthに必要な情報の取得
OAuthに必要な情報の取得

 取得した情報を、次のとおり認証を行うOAuthActivity.javaにセットします。

リスト3 docomo ID認証で必要な情報の設定 (OAuthActivity.javaの抜粋)
/** OAuth 認証用 client id  */
private static final String CLIENT_ID = "xxxxx";
/** OAuth 認証用 client secret  */
private static final String SECRET_ID = "xxxxx";
/** OAuth 認証用 scope  */
private static final String SCOPE = "dialogue";
/** OAuth 認証用 コールバックURL  */
private static final String REDIRECT_URI = "xxxxx";

 今回のチャットアプリのサンプルでは、取得したアクセストークンをPreferencesに保存しています。OAuthActivityクラスの詳細については、本記事の内容からは逸れますのでサンプルコードおよびSDK付属のドキュメントを参照してください。

雑談対話APIのレスポンス

 DialogueAsyncTaskクラスは、雑談対話APIのレスポンスを受け取ります。docomo ID認証によるパーソナライズ機能を使うためには、APIのリクエストに取得したアクセストークンを、リクエストパラメータとともに送信します。パーソナライズ機能を使わない時はAPIの呼び出しはリクエストパラメータのみを送ります。

リスト4 雑談対話APIのレスポンス取得(MainActivity.javaの抜粋)
// 雑談対話要求処理クラスにリクエストデータを渡し、レスポンスデータを取得する
Dialogue search = new Dialogue();
// パーソナライズ機能を利用するときは、リクエストにアクセストークンを送る
boolean oauthFlg = sp.getBoolean("personalize", false);
if ( oauthFlg ) {
    String accessToken = sp.getString("accessToken", "");
    resultData = search.request(reqParam, accessToken);

} else {
    resultData = search.request(reqParam);
}

 雑談対話APIを呼び出すと、以下のような項目がレスポンスとして返ります。このレスポンスから雑談対話の返答(utt)を取得し、画面のListViewコントロールにデータを表示します。

雑談対話APIのレスポンス
内容 項目 データ型 説明
システムの返答 utt string 雑談返答
音声合成用読み出力 yomi string 音声合成用出力
モード mode string 対話のモード
対話番号 da int ユーザとシステムの対話に対してサーバが付与した番号
コンテキストID context string 自動的にシステムより出力されるID

 これで、チャットサンプルアプリの作成がひととおり終わりました。

動作確認

 雑談対話APIのサーバとネットワーク通信を行う必要があるので、最後にAndroidManifest.xmlに以下のパーミッションを設定します。

リスト5 パーミッションの設定(AndroidManifest.xmlの抜粋)
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

 サンプルアプリを実行すると、対話画面が表示されます。筆者が試したところ、対話内容は、会話の文脈をもとに返答されることが多いですが、時々、ニックネームで呼ばれたり、登録した場所の天気やイベント情報などが返答されたりすることもあります。

おわりに

 今回は、雑談対話APIのご紹介と、雑談対話APIを使ったチャットアプリを作りました。コンピュータとの対話を行うには、機械学習や形態素解析などの自然言語処理など、しきいの高い技術を勉強する必要がありますが、docomo APIを使うと短時間で手軽にアプリケーションに組み込むことができることがお分かりいただけたでしょうか。

 「docomo Developer support」では、本連載で紹介した他にもさまざまに有用なAPIを提供しています。本稿で興味を持った人は、ぜひ、他のAPIも触れてみると良いでしょう。

  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

  • WINGSプロジェクト 阿佐 志保(アサ シホ)

    <WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂...

  • 山田 祥寛(ヤマダ ヨシヒロ)

    静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for ASP/ASP.NET。執筆コミュニティ「WINGSプロジェクト」代表。 主な著書に「入門シリーズ(サーバサイドAjax/XM...

All contents copyright © 2005-2022 Shoeisha Co., Ltd. All rights reserved. ver.1.5